How to count identical string elements in a Ruby array

前端 未结 14 2084
感情败类
感情败类 2020-12-02 06:34

I have the following Array = [\"Jason\", \"Jason\", \"Teresa\", \"Judah\", \"Michelle\", \"Judah\", \"Judah\", \"Allison\"]

How do I produce a count for

相关标签:
14条回答
  • 2020-12-02 07:04
    a = [1, 2, 3, 2, 5, 6, 7, 5, 5]
    a.each_with_object(Hash.new(0)) { |o, h| h[o] += 1 }
    
    # => {1=>1, 2=>2, 3=>1, 5=>3, 6=>1, 7=>1}
    

    Credit Frank Wambutt

    0 讨论(0)
  • 2020-12-02 07:06

    Ruby 2.7+

    Ruby 2.7 is introducing Enumerable#tally for this exact purpose. There's a good summary here.

    In this use case:

    array.tally
    # => { "Jason" => 2, "Judah" => 3, "Allison" => 1, "Teresa" => 1, "Michelle" => 1 }
    

    Docs on the features being released are here.

    Hope this helps someone!

    0 讨论(0)
  • 2020-12-02 07:07

    Ruby v2.7+ (latest)

    As of ruby v2.7.0 (released December 2019), the core language now includes Enumerable#tally - a new method, designed specifically for this problem:

    names = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]
    
    names.tally
    #=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}
    

    Ruby v2.4+ (currently supported, but older)

    The following code was not possible in standard ruby when this question was first asked (February 2011), as it uses:

    • Object#itself, which was added to Ruby v2.2.0 (released December 2014).
    • Hash#transform_values, which was added to Ruby v2.4.0 (released December 2016).

    These modern additions to Ruby enable the following implementation:

    names = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]
    
    names.group_by(&:itself).transform_values(&:count)
    #=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}
    

    Ruby v2.2+ (deprecated)

    If using an older ruby version, without access to the above mentioned Hash#transform_values method, you could instead use Array#to_h, which was added to Ruby v2.1.0 (released December 2013):

    names.group_by(&:itself).map { |k,v| [k, v.length] }.to_h
    #=> {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}
    

    For even older ruby versions (<= 2.1), there are several ways to solve this, but (in my opinion) there is no clear-cut "best" way. See the other answers to this post.

    0 讨论(0)
  • 2020-12-02 07:07

    This works.

    arr = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]
    result = {}
    arr.uniq.each{|element| result[element] = arr.count(element)}
    
    0 讨论(0)
  • 2020-12-02 07:10
    names.inject(Hash.new(0)) { |total, e| total[e] += 1 ;total}
    

    gives you

    {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1} 
    
    0 讨论(0)
  • 2020-12-02 07:16

    Now using Ruby 2.2.0 you can leverage the itself method.

    names = ["Jason", "Jason", "Teresa", "Judah", "Michelle", "Judah", "Judah", "Allison"]
    counts = {}
    names.group_by(&:itself).each { |k,v| counts[k] = v.length }
    # counts > {"Jason"=>2, "Teresa"=>1, "Judah"=>3, "Michelle"=>1, "Allison"=>1}
    
    0 讨论(0)
提交回复
热议问题