3

私は配列を持っていarrます。arr条件に基づいて要素を破壊的に削除し、削除された要素を返したいです。

arr = [1,2,3]  
arr.some_method{|a| a > 1} #=> [2, 3]
arr #=> [1]

私の最初の試みはreject!

arr = [1,2,3]  
arr.reject!{|a| a > 1}

しかし、返されるブロックとarrの値は両方とも[1].

カスタム関数を書くこともできますが、これには明示的な方法があると思います。それは何でしょう?

質問に回答した後の更新:

partitionメソッドは、ハッシュに対してもこの動作を実装するのに役立ちます。ハッシュの要素を削除して、削除された要素と変更されたハッシュを返すにはどうすればよいですか?

hash = {:x => 1, :y => 2, :z => 3}
comp_hash, hash = hash.partition{|k,v| v > 1}.map{|a| Hash[a]}
comp_hash #=> {:y=>2, :z=>3}
hash #=> {:x=>1}
4

3 に答える 3

5

ここを使いpartitionます。インプレースで変更しませんselfが、2 つの新しい配列を返します。2 番目の配列を再度割り当てることによりarr、必要な結果が得られます。

comp_arr, arr = arr.partition { |a| a > 1 }

partition のドキュメントを参照してください。

于 2012-12-06T11:38:32.507 に答える
1

末尾の bang を持つすべてのメソッド!はレシーバーを変更します。これらのメソッドが結果のオブジェクトを返すのは慣例のようです。
ただし、できることは次のようなものです。

b = (arr.dup - arr.reject!{|a| a>1 })
b # => [2,3]
arr #=> [1]

これは、名前付けに関するセクションがあるルビースタイルガイドへのリンクです-かなり短いですが

于 2012-12-06T11:24:48.480 に答える
0

削除された要素を返す配列の要素を (その場で) 削除するには、Array クラスのドキュメントに従って、delete メソッドを使用できます。

a = [ "a", "b", "b", "b", "c" ]
a.delete("b")                   #=> "b"
a                               #=> ["a", "c"]
a.delete("z")                   #=> nil
a.delete("z") { "not found" }   #=> "not found"

ブロックを受け入れるため、必要に応じてカスタム動作を追加できます

于 2014-02-05T17:42:56.223 に答える