Counting number of occurrences of element within array or arraylist.
Simple one really. I'm more than happy to do this manually but I was wondering whether or not there are any nifty in-built .net methods that can essentially return either the number of occurrences of each element in an array, or simply return the modal value.
This is fairly straightforward to achieve manually but I was just wondering out of curiosity whether or not Microsoft has already done the work for us here?
Jordan
Re: Counting number of occurrences of element within array or arraylist.
You can do this fairly easily with LINQ.
Code:
Dim arr As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 3, 5, 7, 9}
Dim occurrances = _
arr.GroupBy(Function(v) v).Select(Function(g) New With {.Number = g.Key, .Occurances = g.Count()})
Re: Counting number of occurrences of element within array or arraylist.
Cheers Matt. Great help.
I really should become versed in LINQ.
Re: Counting number of occurrences of element within array or arraylist.
While you can write the line compactly in LINQ, if you compare that to the 'manual' approach you said you could do, you will find that the manual approach is faster. This may change over time, as new versions of the framework might improve the efficiency of LINQ, but at the moment, LINQ is slower for simple loop operations like that. So you reduce the number of lines, but do you really gain? Is the code more easy to read, and is that enough of a benefit to make up for the performance hit, such as it is?
Re: Counting number of occurrences of element within array or arraylist.
Quote:
Originally Posted by
Shaggy Hiker
While you can write the line compactly in LINQ, if you compare that to the 'manual' approach you said you could do, you will find that the manual approach is faster. This may change over time, as new versions of the framework might improve the efficiency of LINQ, but at the moment, LINQ is slower for simple loop operations like that. So you reduce the number of lines, but do you really gain? Is the code more easy to read, and is that enough of a benefit to make up for the performance hit, such as it is?
Always a valid concern.
Is this going to be used more than once? If so you'll incur a performance penalty on the first run through as it's jitted. Each subsequent run-through should be approximately the same.
Is taking a small performance hit worth it to you to make the code more readable and in my opinion maintainable.
It always depends on the context and more often than not I find that LINQ is more beneficial to me than the manual way.
If it's a matter of the LINQ statement being a bottleneck when testing it can always be expanded at a later date. (I cheat and user Refactor! Refactor! Pro.)
Re: Counting number of occurrences of element within array or arraylist.
Quote:
Originally Posted by
Shaggy Hiker
... Is the code more easy to read, and is that enough of a benefit to make up for the performance hit, such as it is?
Easy to read?
I don't do linq yet - I believe I can see a lambda function and some sql-like syntax in that statement - group by??
But easier to read?
I would say that is far from the case.
My initial reaction would be to SORT the array - then counting the occurances of elements becomes elementary. That should be in everyones tool chest.
And that is by far easier to modify in the future.
Modifying a linq statement is like modifying a SQL statement in a sproc - right? You have to understand what it's doing 100% before marching off making changes.
A sort and loop you can step through with the debugger and "watch" it process - seems easier to re-visit a year later IMO...
my two cents ;)
Re: Counting number of occurrences of element within array or arraylist.
Yeah, method syntax isn't going to be as close to SQL as query syntax. Here's a couple of examples using query syntax.
Code:
Dim arr As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 3, 5, 7, 9}
Dim occurences = _
arr.GroupBy(Function(v) v).Select(Function(g) New With {.Number = g.Key, .Occurences = g.Count()})
Dim occurences2 = From num In arr
Group num By num Into NumberCount = Count()
Select New With {
.Number = num,
.Occurences = NumberCount
}
Dim occurences3 = From num In arr
Group By num Into Count()
Select New With {
.Number = num,
.Occurrences = Count
}
The bottom two should look much closer to SQL syntax and be easy to follow. I just prefer method syntax as it's more compact and flows better in my head.
Like I said earlier it's conditional as to whether it's better or not. I prefer it in most situations as the performance hit is usually not noticeable and I find it easier to maintain.
To each their own though.
Re: Counting number of occurrences of element within array or arraylist.
I'd go along with that, with one exception: Intellisense helps you out quite a bit for modifying LINQ, whereas modifying a SQL statement in a sproc gives you less assistance. Otherwise, I'd agree. Complex LINQ statements can be quite interesting, but they increase the information density in a single line of code, which never improves comprehension. On the other hand, simple LINQ statements can be really quick and easy to write, and they aren't at all hard to understand for anybody who knows SQL (there are clear syntactical similarities). Since simple LINQ is slower than a loop, you just have to decide what your strategy is for that particular code. For something that is marginal, such as an item in a tight loop, or one that is in already slow code, I don't use LINQ. If it is some normal user element, where even the fastest mouse-maniacal user is slow as iced pitch (http://en.wikipedia.org/wiki/Pitch_drop_experiment), as far as a computer is concerned, then LINQ is often easier.
The other place I would use LINQ is for any situation where a JOIN would be needed. Those are not easily replaced by a couple loops, and the LINQ may well be faster and smaller than any unrolled alternative.