我有一个数组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}
答案 0 :(得分:5)
我在这里使用partition
。它不会修改self
inplace,但返回两个新数组。通过再次将第二个数组分配给arr
,它可以获得您想要的结果:
comp_arr, arr = arr.partition { |a| a > 1 }
答案 1 :(得分:1)
所有带有尾随爆炸!
的方法都会修改接收器,这似乎是一种约定,这些方法返回结果对象,因为非爆炸这样做。
你可以做的是这样的事情:
b = (arr.dup - arr.reject!{|a| a>1 })
b # => [2,3]
arr #=> [1]
这是指向ruby styleguide的链接,其中有一个关于名称的部分 - 尽管它很短
答案 2 :(得分:0)
要删除(就地)返回已删除元素的数组元素,可以使用delete方法,按照Array class documentation:
a = [ "a", "b", "b", "b", "c" ]
a.delete("b") #=> "b"
a #=> ["a", "c"]
a.delete("z") #=> nil
a.delete("z") { "not found" } #=> "not found"
它接受阻止,因此可以根据需要添加自定义行为