有没有明智的方法来做到以下几点:
我想取一个数组并根据条件从数组中选择特定项,然后将它们从数组中移除.(我基本上想将数组的内容分成几类).
array = [1,2,3,4,5,6,7,8]
less_than_three = array.reject_destructively{|v| v<3}
=> [1,2]
array
=> [3,4,5,6,7,8]
more_than_five = array.reject_destructively{|v| v>5}
=> [6,7,8]
array
=> [3,4,5]
Run Code Online (Sandbox Code Playgroud)
我试过delete_if,选择!,拒绝!并且他们似乎都没有能够给你受影响的物品,而其余的则留下阵列.除非我生气,这完全有可能.
据我了解的问题,您不想产生两个新对象。干得好:
class Array
def carve!
dup.tap { delete_if &Proc.new } - self
end
end
array = [1,2,3,4,5,6,7,8]
p array.carve! { |v| v < 3 }
#? [1, 2] # returned by Array#carve method
p array
#? [3, 4, 5, 6, 7, 8] # remained in original array
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,array.__id__保持不变。这是所有地方中最高尔夫的答案:)
你可以为此建立自己的方法......
class Array
def extract(&block)
temp = self.select(&block)
self.reject!(&block)
temp
end
end
Run Code Online (Sandbox Code Playgroud)
然后...
a = [1, 2, 3, 4, 5]
a.extract{|x| x < 3}
=> [1,2]
p a
=> [3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
编辑:如果你不想猴子补丁(但猴子补丁本身并不邪恶)你可以用香草方法做...
def select_from_array(array, &block)
temp = array.select(&block)
array.reject!(&block)
temp
end
array = [1,2,3,4,5,6,7,8]
less_than_three = select_from_array(array){|v| v<3}
=> [1,2]
array
=> [3,4,5,6,7,8]
more_than_five = select_from_array(array){|v| v>5}
=> [6,7,8]
array
=> [3,4,5]
Run Code Online (Sandbox Code Playgroud)