在遍历数组时如何使用Array#delete?


Answers:


120

a.delete_if { |x| x >= 3 }

在此处查看方法文档

更新:

您可以在代码块中处理x:

a.delete_if do |element|
  if element >= 3
    do_something_with(element)
    true # Make sure the if statement returns true, so it gets marked for deletion
  end
end

1
x如果它被删除,我需要做一些事情。我应该把它放在块里吗?
阿德里安

1
@Adrian或者您可以使用reject!
XåpplI'-I0llwlg'I -

2
要记住的一件事是,如果没有元素被拒绝,reject!它将返回nil,而delete_if返回原始数组。
Jan Klimo 2015年

7

您不必从数组中删除,可以对其进行过滤,以便:

a = [1, 2, 3, 4, 5]

b = a.select {|x| x < 3}

puts b.inspect # => [1,2]

b.each {|i| puts i} # do something to each here

不好意思提出一个僵尸帖子,但对b =方法的一个子集是否增加内存使用率,还是使用内部指针或某些东西引用原始a项感到好奇?我问的原因是我的用例对内存非常敏感,所以好奇是从原始数组中删除还是选择是一种更好的方法……
gorlaz 2015年

@gorlaz.select返回一个新的ruby对象,它将使用更多的内存。参见此示例pastebin.com/23e10bKy
lacostenycoder

从数据不变的意义上讲,这也更具“功能性”。
pedz

4

我不久前问了这个问题。

在Ruby中迭代时删除?

它不起作用,因为Ruby.each在尝试删除某些内容时会退出循环。如果您只是想从数组中删除内容,那是delete_if可行的,但是如果您想要更多控制权,那么我在该线程中拥有的解决方案就可以了,尽管有点难看。


9
删除不会中断循环。each通过使用索引有效地进行迭代。因此,如果删除,索引将不同,下一次迭代将使用新索引。试试这个:arr = [1,2,3,4,5,6]; arr.each_with_index {|e,i| p [arr, e, i]; next if e < 3; arr.delete e }。到达第3项时,索引为2。删除3后,下一个迭代将索引递增为3,并且该项为5。因此跳过了4。出于相同的原因,跳过了6。
开尔文

3

这样做的另一种方法是使用reject!,它可以说更清晰,因为它具有!表示“这将改变数组”的含义。唯一的区别是,如果不进行任何更改,reject!它将返回nil

a.delete_if {|x| x >= 3 }

要么

a.reject! {|x| x >= 3 }

都可以正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.