拒绝来自array,mutate数组的元素以获得非拒绝元素,并返回被拒绝的

时间:2016-09-08 19:42:17

标签: arrays ruby

我有一个数组,其中我想要过滤它的元素,并改变它以删除那些元素,不仅我需要过滤以返回带有过滤元素的新数组,如下所示:

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

但是我有一个包含嵌套哈希的数组,并且复制它不会是一个好主意,并且会让我变得很糟糕。所以我问是否有任何内置方法或好方法直接这样做。

4 个答案:

答案 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]