找出哪个对象在ruby中有n个实例

时间:2012-08-28 13:59:57

标签: ruby arrays find instance

我有一个数组:x = [a,b,c,d,e,f,g,h],可以有1到9个对象

首先,我必须计算IF中的任何一个对象是否存在3次。我不想写

if (x.count(1) == 3) or (x.count(2) == 3) ...etc... 

有没有办法缩短这个,如下所示?

x.count { |obj| obj } == 3 

其次,如果我知道有3个实例找到了一个对象,我该怎么知道它是哪一个? (1或2或3 .....)

1 个答案:

答案 0 :(得分:0)

x = [:a, :b, :b, :b, :c, :c, :c]
counted = Hash[
  x.group_by do |e|
    x.count(e)
  end.map do |count, items|
    [count, items.uniq]
  end
]
p counted[3]    #=> [:b, :c]

这是如何工作的?让我们按照步骤。首先,让我们按计数对项目进行分组:

grouped_by_count = x.group_by do |e|
  x.count(e)
end

这会生成一个散列,其中键是计数,值是具有该计数的非唯一项的列表:

p grouped_by_count
#=> {1=>[:a], 3=>[:b, :b, :b, :c, :c, :c]}

我们真的宁愿拥有唯一的项目,所以让我们做这个转变:

grouped_by_count_unique = grouped_by_count.map do |count, items|
  [count, items.uniq]
end
p grouped_by_count_unique
#=> [[1, [:a]], [3, [:b, :c]]]

这给了我们一个数组数组,而不是哈希。幸运的是,将数组数组转换为哈希很容易:

counted = Hash[grouped_by_count_unique]
p counted
# => {1=>[:a], 3=>[:b, :c]}

现在只需将各个部分放在一起,消除临时性,你就会得到最顶层的答案。