Making a count of unique elements in an array

Discussion in 'Ruby' started by Dan Kohn, Jan 9, 2006.

  1. Dan Kohn

    Dan Kohn Guest

    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]]
     
    Dan Kohn, Jan 9, 2006
    #1
    1. Advertisements

  2. I like #inject 1-liners:
    => [["a", 1], ["b", 2], ["c", 2], ["d", 1], ["e", 3]]

    :)

    Kind regards

    robert
     
    Robert Klemme, Jan 9, 2006
    #2
    1. Advertisements

  3. Dan Kohn

    vsingla160 Guest

    if i have to count no. of distinct elements in a 2D array ,then what to do??
     
    vsingla160, Dec 12, 2013
    #3
  4. 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
     
    Norbert Melzer, Dec 12, 2013
    #4
  5. Iterate and count. For counting you can use a Hash with default value 0.

    Cheers

    robert
     
    Robert Klemme, Dec 14, 2013
    #5
  6. Dan Kohn

    lukeabergen Guest

    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]}
     
    lukeabergen, Dec 26, 2013
    #6
  7. 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
     
    Robert Klemme, Dec 28, 2013
    #7
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.