2016-07-20 4 views
0

配列を繰り返し処理する方法があります。これらの条件によってはいくつかのものを削除したい要素。私が削除したいインデックスを追跡するために、それぞれをeach_with_indexループに変換し、削除したい要素のインデックスを配列index_arrayに格納します。元の配列のインデックスにあるアイテムを正確に削除するにはどうすればよいですか? index_arrayをループし、delete_atを使用すると、元のインデックスが変更されます。以下のシナリオの説明を参照してください:ルビーの他の配列から配列内に定義されている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

ようこそスタックオーバーフロー。私たちはこれを解決するためのあなたの努力の証拠を見たいと思います。あなたが試したことがないように見えますが、私たちにあなたのためにそれを書いてもらいたいのですが、これはSOのためではありません。 「[ask]」とリンク先のページをお読みください。 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] 

それ以降のすべてのアイテム、エルゴsort.reverse_eachのインデックスが変更された項目を削除するため、アレイの端部から削除することが重要です。配列が既にソートされていることがわかっている場合は、reverse_eachを実行します。

あなたがdelete_these_indices配列を変更する試合気にしない場合は、多少簡潔になります

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

再びあなたがdelete_these_indicesがすでにソートされている知っていれば、あなたはsort!をスキップすることができます。

+0

これを行うにはルビーの魔法がい​​くつかあると願っていましたが、これもかなり上品な解決策です!ありがとうございました – Reinier

+0

FWIW私は少し簡潔な解決策で私の答えを編集しました。 –

+0

これは、メソッドにパッケージ化した場合、最後の行に 'my_array'を追加する必要があることに注意する価値があります。 –

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

あなたはケースのように思われる(my_arrayを変更したい場合は希望インデックス以前に削除されたどのように多くの考慮に入れて、その

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.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が有効な値)として扱う場合、nilを使用すると問題が発生します。

技術的には、各配列を一度反復していますが、あなたの削除可能な値人々は不快です。

+0

私が意図せず無視したコーナーケースは、削除するインデックスのいずれかが、削除する配列のサイズよりも大きい場合です。 – jaydel

+1

'my_array.delete(nil)'の代わりに 'my_array.compact!'をお勧めしますか? –

+0

ああ、良い電話、@ジョーダン – jaydel

関連する問題