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 

第 2 に、オブジェクトが 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 に答える