オブジェクトの配列があり、その多くは配列に何回も表示されます。 1つのアイテムの特定の場所へのインデックスがあります。私はインデックスを維持しながら、すべての場所で配列から1つのオブジェクトを削除したい。削除されたアイテムへのインデックスは、次に使用可能なアイテムに移動し、存在しない場合は、配列の先頭に折り返さなければなりません。配列を保持するインデックスからアイテムを削除する
array = [:b, :a, :b]
index = 2
今すぐ配列から:a
を削除し、第二:b
があるので、インデックスは今、1を次のようになります。
私は、私は非常によくそれを説明していないと思うので、ここで簡単な例を示します現在インデックス1に設定されています。
インデックスが削除されたオブジェクトを指しているとしましょう。インデックスは、次に使用可能なオブジェクトに移動する必要があります。したがって、インデックスが1の場合は、:b
を指しており、すぐ後に:a
が続きますので、インデックスは変更されません。
ここではラップアラウンド例です:あなたは:a
を削除した場合、インデックスは次の使用可能なインデックスにラップアラウンドする必要があり、または0
はシンプルようだが、はるかに複雑なエッジケースがある
array = [:b, :a]
index = 1
。削除した後
array = [:a, :a, :b, :a, :c, :b, :a]
:ここで私は考えることができる最も複雑な例です「:A」、結果の配列は[:b, :c, :b]
です。彼らは0、0、0、1、1、2に変更する必要があり、すべての可能な開始インデックス(0~6)から、0
は、アレイ内の複数のオブジェクトが存在すると仮定し、それは、削除後の空になることはありません。
(編集)私は私がこれまで試したものを含むべきであることを私に知らせるための@Raffaelへ
感謝。ここに私の最初の試みがあった:
@items
は配列です。@current_item_index
は、調整が必要な指標です。item
は削除されるアイテムです。
コード:
indexes = @items.each_index.each_with_object([]) do |i, memo|
memo << i if @items[i] == item
end
indexes.reverse.each do |i|
@items.delete_at(i)
@current_item_index -= 1 if i < @current_item_index
@current_item_index = 0 unless @current_item_index < @items.size
end
それだけで非常に "ルビー"(クリアも簡潔ではないが)いないようでした。また、それはリストを2回実行するので、それほどパフォーマンスが良いようには見えません - 良いことはできないすべてのそれらのdelete_at
の呼び出しはもちろんです。
なぜこれを行うのですか。つまり、使用状況は何ですか?あなたの最終目標を達成するためのより良い方法はないでしょうか? – pjs
あなたは40分以上前にこの質問をしました。答えはなく、コメントは1つだけです。つまり、誰もあなたの質問を理解することはできません。あなたの最初の例では、 'index = 2'であっても、インデックス1にある':a'を削除します。あなたがそうするように導くルールは何ですか? 'index-1'で要素を削除していたと思います。しかし、第2の例では、 'index = 1'のときに':b'が削除されることを期待していましたが、インデックス 'index - 1#=> 0'にあるので、' 'a''インデックス1、それは削除されます。明確にするために質問を編集してください。 –
@pjs:現在のプレーヤーを追跡するインデックスを持つ、ゲーム内のプレーヤーのリストがあります。プレイヤーは複数のターンを持つことがあるので、アレイに複数回いる。このアルゴリズムは、プレイヤーがゲームを終了するときに実行されるように意図されています。私は、より良いものが提示されれば、表現をリファクタリングすることに完全にオープンです。 –