7

私はミュージカルトラックの配列を持っていますが、この配列では、複数のアルバムでリリースされているため、同じ曲が複数回表示される可能性があります。真の一意のものだけがリストに表示されるように、それらを配列から削除しようとしています。

ハッシュは次のようになります。

"tracks" => [
    [0] {
        "id" => 1,
        "Title" => "Intergalactic",
        "ArtistName" => "Beastie Boys"
    },
    [1] {
        "id" => 2,
        "Title" => "Intergalactic",
        "ArtistName" => "Beastie Boys"
    }
]

Titleキーに基づいて重複を削除する方法が必要です。とにかくこれを行う?

4

3 に答える 3

11

ActiveSupportを使用している場合は、次のようにuniq_byを使用できます。

tracks.uniq_by {|track| track["title"]}

そうでない場合は、自分で簡単に実装できます。これを参照してください。

# File activesupport/lib/active_support/core_ext/array/uniq_by.rb, line 6
  def uniq_by
    hash, array = {}, []
    each { |i| hash[yield(i)] ||= (array << i) }
    array
  end
于 2011-10-06T18:08:11.757 に答える
10

1.9のArray#uniq!メソッドはブロックを取るので、ハッシュが次のh場合:

h['tracks'].uniq! { |x| x['Title'] }

1.8を使用している場合は、次のように偽造できます。

h['tracks'] = h['tracks'].group_by { |x| x['Title'] }.values.map(&:first)

その場で変更したいと思います。

于 2011-10-06T18:45:29.427 に答える
0

他の方法は正しいですが、SOの他の場所で見つけた余分な砂糖を少し入れます。

このSymbolの拡張機能の使用:

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

次のような単純な反復ブロックを作成する代わりに

foo_array.each{ |foo| foo.update_bar("baz") }、これで使用できます

foo_array.each &:update_bar.with("baz")

あなたが書くかもしれない方法に似ていますmaybe_nil.try(:[], "key")...

foo_array.uniq{ |foo| foo["key"] }と同じになりました

foo_array.uniq(&:[].with("key"))

これがお役に立てば幸いです

于 2019-07-01T18:03:21.037 に答える