Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Making a count of unique elements in an array

1,789 views
Skip to first unread message

Dan Kohn

unread,
Jan 9, 2006, 1:47:16 AM1/9/06
to
Given an array, I need to produce a two-dimensional resulting array
where each pair consists of a unique element from the original array
and the number of times that element appears.

I found two ways to do this. Is one of them better? Is there a better
way?

arr = %w{a b b c c d e e e}
p arr
p arr.uniq.map {|e| [e, (arr.select {|ee| ee == e}).size ]}
counter = {}
arr.each {|e| counter[e] += 1 rescue counter[e] = 1 }
p counter.to_a


outputs:

["a", "b", "b", "c", "c", "d", "e", "e", "e"]
[["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]
[["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]

Peña, Botp

unread,
Jan 9, 2006, 2:07:47 AM1/9/06
to
Dan Kohn [mailto:d...@dankohn.com] wrote:

#counter = {}
#arr.each {|e| counter[e] += 1 rescue counter[e] = 1 }
#p counter.to_a

me, like the above but w slight modif below:

irb(main):013:0> counter2 = Hash.new(0)
=> {}
irb(main):014:0> arr.each {|e| counter2[e] += 1 }
=> ["a", "b", "b", "c", "c", "d", "e", "e", "e"]
irb(main):015:0> counter2.to_a
=> [["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]
irb(main):016:0>

(note the plain counter and the hash param)

hth.

kind regards -botp


Robert Klemme

unread,
Jan 9, 2006, 5:07:58 AM1/9/06
to

I like #inject 1-liners:

>> arr = %w{a b b c c d e e e}

=> ["a", "b", "b", "c", "c", "d", "e", "e", "e"]
>> arr.inject(Hash.new(0)) {|h,x| h[x]+=1;h}
=> {"a"=>1, "b"=>2, "c"=>2, "d"=>1, "e"=>3}
>> arr.inject(Hash.new(0)) {|h,x| h[x]+=1;h}.to_a
=> [["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]
>> arr.inject(Hash.new(0)) {|h,x| h[x]+=1;h}.sort
=> [["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]

:-)

Kind regards

robert

vsing...@gmail.com

unread,
Dec 12, 2013, 12:56:28 PM12/12/13
to
if i have to count no. of distinct elements in a 2D array ,then what to do??

Norbert Melzer

unread,
Dec 12, 2013, 1:44:47 PM12/12/13
to
On 12.12.2013 18:56, vsing...@gmail.com wrote:

> if i have to count no. of distinct elements in a 2D array ,then what
> to do??

I think at least one of this will do it:

```
[1] pry(main)> [[1,2],[2,3],[1,2]].count
=> 3
[2] pry(main)> [[1,2],[2,3],[1,2]].uniq
=> [[1, 2], [2, 3]]
[3] pry(main)> [[1,2],[2,3],[1,2]].uniq.count
=> 2
[4] pry(main)> [[1,2],[2,3],[1,2]].flatten
=> [1, 2, 2, 3, 1, 2]
[5] pry(main)> [[1,2],[2,3],[1,2]].flatten.uniq
=> [1, 2, 3]
[6] pry(main)> [[1,2],[2,3],[1,2]].flatten.uniq.count
=> 3
```

There is a very beautiful ressource:
<http://www.ruby-doc.org/core-2.0.0/Array.html>

You can find nearly anything about arrays there�

HTH
Norbert

Robert Klemme

unread,
Dec 14, 2013, 11:22:03 AM12/14/13
to
On 12.12.2013 18:56, vsing...@gmail.com wrote:
> if i have to count no. of distinct elements in a 2D array ,then what to do??

Iterate and count. For counting you can use a Hash with default value 0.

Cheers

robert


lukea...@gmail.com

unread,
Dec 26, 2013, 4:44:23 PM12/26/13
to
Another way is the super-useful group_by and map

arr = ["a", "b", "b", "c", "c", "d", "e", "e", "e"]
grouped = arr.group_by {|x| x} #=> produces something like {"a" => ["a"], "b" => ["b", "b"], etc...
result = grouped.map {|el, arr| [el, arr.count]}

Robert Klemme

unread,
Dec 28, 2013, 6:02:41 AM12/28/13
to
Downside of that approach is that it does unnecessary work and uses more
memory than necessary. And the result is not a Hash which may make
retrieval of the counts of an element quite expensive if there are many
different values.

Btw, the OP spoke of a "2D array". So the input likely looks different
than in your example. We also do not know what he actually wants to
count. Is it individual elements? Or does "distinct elements" refer to
a single array?

Kind regards

robert

0 new messages