我使用的是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"]
注意结束数组。因为我从10开始,然后在数组中指定要删除的三个元素索引,所以我应该只有七个元素。但我有八个要素。如何调整我的语句以删除我指定的索引处的元素?
答案 0 :(得分:3)
每次从数组中删除项目时,索引都会更改。
所以你可以这样做:
3.times { a.delete_at(7) }
与7,8,9的删除效果相同
或按照此处的建议使用slice!
:{{3}}
a.slice!(7..9)
使用任意数组,我认为明显的选择是拒绝索引:
a.reject.with_index { |item, idx| indexes_to_delete.include? idx }
这是非变异的,因此您可以设置一个等于结果的变量。
答案 1 :(得分:1)
以下是一些方法。
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
),这对我来说是最好的。我怀疑三者之间存在显着的效率差异。
答案 2 :(得分:1)
您的问题是执行删除时索引会发生更改。所以最初不要删除。
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)