我正在使用Ruby 2.4。 如果我有一组数组索引,并且我想删除这些索引中的所有元素,我该怎么做? 我尝试了以下内容,但它遗漏了东西
2.4.0 :005 > indexes_to_delete = [7, 8, 9]
=> [7, 8, 9]
2.4.0 :008 > a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
2.4.0 :009 > indexes_to_delete.each do |index| a.delete_at(index) end
=> [7, 8, 9]
2.4.0 :010 > a
=> ["a", "b", "c", "d", "e", "f", "g", "i"]
请注意结束数组。 我应该在数组中只有七个元素,因为我从十个开始,然后指定了三个要在数组中删除的元素索引。 然而,我有八个要素。 如何调整语句以删除指定索引处的元素?
每次从数组中删除项目时,索引都会更改。
所以你可以这样做:
3.times { a.delete_at(7) }
在 7,8,9 处具有相同的删除效果
或者按照此处的建议使用slice!
:如何从数组中删除一系列值?
a.slice!(7..9)
要使用任意数组,我认为显而易见的选择是拒绝索引:
a.reject.with_index { |item, idx| indexes_to_delete.include? idx }
这是非变异的,因此您需要设置一个等于结果的变量。
这里有几种方法可以做到这一点。
indexes_to_delete = [3, 8, 9]
a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
#1
indexes_to_delete.sort.reverse_each { |i| a.delete_at(i) }
a #=> ["a", "b", "c", "e", "f", "g", "h"]
这会a
.如果不需要,请在 a
(a.dup
( 的副本上进行操作。
请记住,您必须按照索引的相反顺序删除元素。
#2
a.values_at(*(0..a.size-1).to_a - indexes_to_delete)
#=> ["a", "b", "c", "e", "f", "g", "h"]
首先我们计算"守门员">
(0..a.size-1).to_a - indexes_to_delete
#=> [0, 1, 2, 4, 5, 6]
这不会a
突变。如果要a
突变,则写入
a.replace(a.values_at(*(0..a.size-1).to_a - indexes_to_delete))
#=> ["a", "b", "c", "e", "f", "g", "h"]
a #=> ["a", "b", "c", "e", "f", "g", "h"]
@maxple给出了第三种方式(reject.with_index
(,对我来说读起来最好。我怀疑这三者之间是否存在显着的效率差异。
您的问题是删除时索引会更改。 所以一开始不要删除。
a = ["a","b","c","d","e","f","g","h","i","j"]
to_delete = [7,8,9]
to_delete.each { |i| a[i] = nil }
a.compact!
将要删除的元素设置为 nil,然后压缩数组以删除这些元素。
如果你有想要保留的 nil 元素,但你知道数组中永远不会有一个值,你可以这样做
MARK = special value
to_delete.each { |i| a[i] = MARK }
a.delete(MARK)