如何原地删除数组元素并返回删除的元素。

4

我有一个数组arr。我想根据条件从arr中破坏性地删除元素,并返回已删除的元素。

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

我第一次尝试的结果是拒绝!

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}
3个回答

5

我会使用partition函数。它不会改变原有的数组self,但是会返回两个新数组。通过将第二个数组再次赋值给arr,就可以得到你想要的结果:

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

查看partition方法的文档


1
所有带有感叹号!的方法都会修改接收器,似乎惯例是这些方法返回结果对象,因为非感叹号方法也是如此。
不过你可以像这样做:
b = (arr.dup - arr.reject!{|a| a>1 })
b # => [2,3]
arr #=> [1]

这里有一个链接Ruby风格指南,其中有一个关于命名的章节 - 尽管它相当简短


0

要在原地删除数组元素并返回已删除的元素,可以使用 delete 方法,如 Array 类文档 所述:

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

它接受块,因此可以根据需要添加自定义行为


“delete” 不允许指定条件(a > 1),并且正如您的示例所示,它仅返回最后删除的项目,即使已删除多个项目。 - Stefan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接