2
c = %w(a b c d)
1.8.7 :025 > c.uniq {|x|x[/^a/]}
=> ["a", "b"] 
1.8.7 :026 > c.uniq {|x|x[/^b/]}
=> ["a", "b"] 
1.8.7 :027 > c.uniq {|x|x[/^c/]}
=> ["a", "c"] 
1.8.7 :029 > c.uniq {|x|x =~ [/^c/]}
=> ["a"] 
1.8.7 :030 > c.uniq {|s|s[/[^abc]/]}
=> ["a", "d"]

正規表現を理解していますが、uniqブロックがどのように機能するのかわかりません。

4

3 に答える 3

4

それは少しトリッキーなものです。

c = %w(a b c d)
1.8.7 :025 > c.uniq {|x|x[/^a/]}
=> ["a", "b"] 

このxブロックのは、配列内のすべての値です。「文字列は?で始まりaますか?」によって一意性を定義します。値aは最初に評価されるtrueため、最初の値です。bが最初に評価されfalse、2番目の値も同様です。ともcとしてd評価されますが、評価された値がすでに見つかっfalseているため、一意ではありません。false

1.8.7 :026 > c.uniq {|x|x[/^b/]}
=> ["a", "b"] 

ここでも同じことが言えます。a最初の(false)とb2番目の(true)です。

1.8.7 :027 > c.uniq {|x|x[/^c/]}
=> ["a", "c"] 

ここでaは、それが最初のfalse値でありc、評価する最初の値であるtrueため、2番目の一意の値であることがわかります。

1.8.7 :029 > c.uniq {|x|x =~ [/^c/]}
=> ["a"] 

ここでは、「文字列がcで始まらない文字列と一致する正規表現の配列と一致するか」によって一意性を定義しました。変!

1.8.7 :030 > c.uniq {|s|s[/[^abc]/]}
=> ["a", "d"]

ここでは、文字クラスを定義しました。「a、b、またはcを含む文字列」によって一意性を定義しました。aとして最初に満たすのはtrueです。dとして評価する唯一の値falseです。

お役に立てば幸いです。

于 2011-10-14T15:27:52.597 に答える
0

一意性の決定は、各要素をブロックに渡した結果に基づいています。

したがって、たとえば、最初の要素は、各要素が「a」であるかどうかを尋ねることを表します。最初のものは「はい」と言っているので、「a」は一意であると見なされます。2つ目は「いいえ」と言っているので、「b」は一意であると見なされます。他の人も「いいえ」と言っているので、それらは一意であるとは見なされません(「いいえ」という応答はすでに見たものであるため)。

ただし、簡単に説明できないのは、Ruby1.8.7でこれが機能しているように見える理由です。1.8.7以前では、Array#uniqのブロック引数は無視されていました。この機能はRuby1.9で追加されました。おそらくあなたはパッチを当てたバージョンを持っていますか?

于 2011-10-14T15:24:13.013 に答える
0

このように見てください。uniqブロックで使用する場合、各内部配列がある配列の配列を効果的に構築[result_of_block, array_element]し、最初の要素で一意の値を探します。したがって、次のように始めると、

c = %w(a b c d)

見て

c.uniq {|x|x[/^a/]}

その場合、配列の配列は次のようになります。

[
    ['a', 'a'],
    [nil, 'b'],
    [nil, 'c'],
    [nil, 'd']
]

最初の要素の中から一意の値を探すと、次のように'a'なりnilます。

[
    ['a', 'a'],
    [nil, 'b']
]

とアンラッピングはをもたらし['a', 'b']ます。'b'ただし、2番目の要素として取得できるという保証はありません。

あなたはこのようにあなた自身を書くことができますuniq_by

def uniq_by(a, &block)
    Hash[a.map { |x| [ block.call(x), x] }].values
end

またはこれ:

def uniq_by(a, &block)
    h = { }
    a.each { |x| h[block.call(x)] = x ] }
    h.values
end
于 2011-10-14T16:10:26.487 に答える