所以,我很清楚在迭代块中删除项目的危险(这是反向循环),我知道 Matz 提到了一些关于迭代中的突变导致稳定性问题,但我似乎无法弄清楚这一点.
这个例子有点复杂,我不确定即使解决它也会完全复制这个例子,但我必须尝试。
arr1 = [1, 2, 3, 4, 5]
arr2 = [3, 4, 5]
puts arr1.inspect
puts arr2.inspect
arr2.each do |i|
arr1.reverse.each_with_index do |j, index|
if i == j
arr1.delete_at(index)
end
end
end
puts arr1.inspect
puts arr2.inspect
输出:
[1, 2, 3, 4, 5]
[3, 4, 5]
[4, 5]
[3, 4, 5]
什么时候应该:
[1, 2, 3, 4, 5]
[3, 4, 5]
[1, 2]
[3, 4, 5]
将 delete_at(index) 更改为 delete(j) 可以解决此问题,但当数组是对象时不起作用。我还将对象复制到临时数组以使事情变得更加复杂。
在我的现实生活场景中,我有两个数组,其中填充了不同类型的 Model 对象,但共享一个公共属性(可能在这里使用连接,但我试图避免使用特殊的连接表)。我想要的是删除array1 中所有在array2 中具有共同属性的对象。我尝试了许多不同的方法,但没有解决方案……太多了,无法放在这里。
@arr1 = []
original_arr1 = Model1.where(...)
original_arr1.each { |original| @arr1 << original.dup }
@arr2 = Model2.where(...)
@arr2.each do |object1|
@arr1.reverse.each_with_index do |object2, index|
if object1.color == object2.color
@arr1.delete_at(version_index)
end
end
end
如果没有上面的额外复制,模型关联将保留,我最终会从表中删除记录,这不应该发生。这只是一个临时清单。这似乎是一个愚蠢的问题,我花了太多时间在它上面。