我有一个数组,其中我想要过滤它的元素,并改变它以删除那些元素,不仅我需要过滤以返回带有过滤元素的新数组,如下所示:
array = [1, 2]
rejected_elements = array.rejection_method! {|a| a == 1} => [1]
rejected_elements => [1]
array => [2]
Ruby中是否有内置方法可以这样做?
以下是我的尝试:
dupped_array = array.dup
rejected_elements = array.reject! {|a| a == 1}
array = dupped_array - rejected_elements
但是我有一个包含嵌套哈希的数组,并且复制它不会是一个好主意,并且会让我变得很糟糕。所以我问是否有任何内置方法或好方法直接这样做。
答案 0 :(得分:2)
也许是这样的?
array = [1,2,3,4,5,6,7]
rejected = array.map { |a| array.delete(a) if a.even? }.compact
答案 1 :(得分:1)
我不知道是否有内置方法可以做到这一点。 Array#reject!
和Array#delete_if
修改数组,但不返回被拒绝的元素。所以,这是一个自定义方法,可以满足您的要求:
def rej_method(arr, n)
a = arr - arr.reject {|i| i==n }
arr.delete(n)
a
end
然后根据你的例子:
array = [1, 2]
rejected_elements = rej_method(array, 1)
rejected_elements #=> [1]
array #=> [2]
考虑使用Enumerable#partition
方法,例如:
arr = [1, 2, 3, 4, 5]
arr.partition {|i| i==1 } #=> [[1], [2, 3, 4, 5]]
答案 2 :(得分:0)
如果你不介意重新分配array
,你可以这样做:
array = [1, 2]
predicate = ->(member) { member == 1 }
array, rejects = array.inject([[],[]]) { |(keep, discard), member|
if predicate.call(member)
[keep, discard.push(member)]
else
[keep.push(member), discard]
end
}
array => [2]
rejects => [1]
答案 3 :(得分:0)
def remove_ns(arr, n)
[n]*(arr.size - ((arr.delete(n) || arr) && arr).size)
end
arr = [1,2]
remove_ns arr, 1
#=> [1]
arr
#=> [2]
arr = [1,1,2,2]
remove_ns arr, 1
#=> [1, 1]
arr
#=> [2, 2]
arr = [1,2]
remove_ns arr, 3
#=> []
arr
#=> [1, 2]