【问题标题】:Concise way of reducing a Ruby array to the count of unique values? [duplicate]将Ruby数组减少为唯一值计数的简洁方法? [复制]
【发布时间】:2014-10-28 03:13:49
【问题描述】:

我有一个看起来像这样的 Ruby 数组:

animals = %w(dog cat bird cat dog bird bird cat)

我需要计算数组中每个唯一项的计数。我可以这样做:

dogs = 0
cats = 0
birds = 0

animals.each do |animal|
  dogs += 1 if animal == 'dog'
  cats += 1 if animal == 'cat'
  birds += 1 if animal == 'bird'
end

...但是这种方法太冗长了。在 Ruby 中计算这些唯一计数的最简洁方法是什么?

【问题讨论】:

标签: ruby arrays count unique


【解决方案1】:

我猜你要找的是count:

animals = %w(dog cat bird cat dog bird bird cat)
dogs = animals.count('dog') #=> 2
cats = animals.count('cat') #=> 3
birds = animals.count('bird') #=> 3

【讨论】:

  • 哦,有趣!我不知道 count 接受参数!
  • +1,我也不知道
【解决方案2】:
animals.uniq.map { |a| puts a, animals.count(a)}

【讨论】:

    【解决方案3】:

    使用group_by的另一种方法

    animals = %w(dog cat bird cat dog bird bird cat)
    hash = animals.group_by {|i| i}
    hash.update(hash) {|_, v| v.count}
    
    #=> hash = {"dog"=>2, "cat"=>3, "bird"=>3}
    

    【讨论】:

    • 你的最后一行很酷。我熟悉 update 的形式,它需要一个块,但我还没有看到它本身带有一个散列 merge!d。您可以考虑将块变量写为|_,v,_|
    【解决方案4】:

    最简单的方法是将计数存储在哈希中,如下所示:

    animals = %w(dog cat bird cat dog bird bird cat)
    animal_counts = {}
    animals.each do |animal|
      if animal_counts[animal]
        animal_counts[animal] += 1
      else
        animal_counts[animal] = 1
      end
    end
    

    这会将数组中的每个唯一项存储为键,并将它们计为值。它改进了您的代码,因为它不需要预先了解数组的内容。

    【讨论】:

    • 嗯,这对我来说似乎有点矫枉过正。你说你不需要预先了解数组的内容,我同意,没错。但是,如果您不将 dogcatbird 的计数作为新创建的 Hash 中的键传递,您将如何访问它们?
    • 您可以将其简化为:animals.each_with_object({}) {|a,c| c[a] = (c[a] ||= 0)+1} => {"dog"=>2, "cat"=>3, "bird"=>3}
    猜你喜欢
    • 1970-01-01
    • 2017-12-31
    • 2017-05-16
    • 2021-03-26
    • 2023-01-12
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多