1

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

首先,我必须计算这些对象是否存在 3 次。我不想写

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

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

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

其次,如果我知道一个对象已经找到了 3 个实例,我怎样才能找出它是哪一个?(1个或2个或3个......)

4

1 回答 1

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]}

现在只需将这些部分放在一起消除临时性,您就会在顶部得到答案。

于 2012-08-28T14:21:47.043 回答