2016-07-20 49 views
0

我有一个迭代数组的方法,在某些条件下做了一堆事情,并且根据这些条件我还想删除一些要素。为了跟踪我想要删除的索引,我将each转换为each_with_index循环,并将我想要删除的元素的索引存储在数组index_array中。我怎样才能删除我的原始数组中的这些索引上的项目?遍历index_array并使用delete_at会改变原始索引。请参阅下面的场景描述:我怎样才能从ruby中的其他数组中删除某些数组中定义的某些indeces

> my_array = [0,1,2,3,4,5,6,7] 
> delete_these_indexes = [1,2,5] 
the desired result is: 
> my_array => [0,3,4,6,7,8] 
+0

欢迎来到Stack Overflow。我们希望看到你解决这个问题的努力的证据。因为它看起来像你没有尝试,并希望我们为你写,这不是它的目的。请阅读“[问]”和链接的页面。 http://meta.stackoverflow.com/q/261592/12842也是有用的阅读。 –

回答

3

这个怎么样?

my_array = [0, 1, 2, 3, 4, 5, 6, 7] 
delete_these_indices = [1, 2, 5] 

delete_these_indices.sort.reverse_each {|i| my_array.delete_at(i) } 

p my_array 
# => [0, 3, 4, 6, 7, 8] 

它从数组末尾删除,因为删除的项目将改变所有后续项目,ERGO sort.reverse_each的指标是很重要的。如果你知道阵列已经排序,你可以做reverse_each

如果你不关心回合修改delete_these_indices阵列,可以在一定程度上更简洁:

delete_these_indices.sort! 
my_array.delete_at(i) while (i = delete_these_indices.pop) 

同样,你可以跳过sort!,如果你知道delete_these_indices已经排序。

+0

希望能有一些红宝石的魔力来做到这一点,但这也是一个相当优雅的解决方案!谢谢 – Reinier

+0

FWIW我用一个稍微简洁的解决方案编辑了我的答案。 –

+0

值得注意的是,如果你在一个方法中打包,你需要添加'my_array'作为最后一行。 –

0
delete_these_indexes.each_with_index do |val, i| 
    my_array.delete_at(val - i) 
end 

将删除所需的索引考虑到有多少人之前被删除,并调整该

https://repl.it/CeHZ

+0

索引在每次迭代中是否更改?这意味着如果您试图删除索引3和5并删除索引3,索引5中的内容是否会移至索引4? – jaydel

+0

@jaydel是他们做的!如果您不期待它可能会很麻烦 – larz

1
keep_these_indexes = my_array.each_index.to_a - delete_these_indexes 
    #=> [0, 3, 4, 6, 7] 

如果要修改my_array(这似乎是这样的):

my_array.replace(my_array.values_at(*keep_these_indexes)) 
    #=> [0, 3, 4, 6, 7] 

如果不是:

new_array = my_array.values_at(*keep_these_indexes) 

请参阅Array#values_at

+0

- 操作符不适用于索引,而是适用于对象。它是内容对象的集合运算符,而不是索引 – jaydel

+0

@jaydel,即[Array# - ](http://ruby-doc.org/core-2.3.0/Array.html#method-i-2D)。 –

+0

我不关注。 'to_a'返回一个Array对象,所以你的片段'my_array.each_index.to_a_delete_these_indexes'不是按索引而是按值返回差异。对不起,如果我在这里很厚。当天晚些时候... – jaydel

0

可能不是最好的答案,但你可以做到这一点还有:

delete_at_indices.each {|ind| my_array[ind] = nil } 
my_array.delete(nil) 

注意到第一遍概念性数据在指定的索引无效,则调用.delete会吹出来的任何值匹配通过的内容。

此解决方案假定您可以定义对您的阵列无效的值。使用零将会有问题,如果你把它当作一个人口稀疏的数组(其中nil是一个有效的值)

从技术上讲,你是遍历每个数组一次,但是,绅士的协议,你可删除的值可能会使一些让人不舒服

+0

一个角落案例我无意中忽略了是否删除的任何索引都大于要清除的数组大小。 – jaydel

+1

可能我建议'my_array.compact!'而不是'my_array.delete(nil)'? –

+0

哦,很好的电话,@Jordan – jaydel