JavaScript配列を使用する代わりに、リンクリストを実装したいと思います。
JSアレイについての真実
まず、配列について誤解している可能性があります。JavaScript配列について考えるとき、実際には、キーがたまたま整数であるハッシュマップについて話しています。そのため、配列は数値以外のインデックスを持つことができます。
L = [];
L[1] = 4
L["spam"] = 2;
配列の反復は(少なくともC / C ++の意味では)高速ですが、ハッシュマップを介した反復はかなり貧弱です。
あなたの場合、特定の制約が満たされた場合、一部のブラウザは実際の配列を実装する可能性があります。しかし、実際の配列も必要ないと確信しています。
アレイのパフォーマンス
実際の配列でさえ、あなたがやりたいことに特に従順ではありません(あなたが指摘したように、あなたundefined
が弾丸を削除しても、あなたの配列は要素でいっぱいになり続けます!)
そして、実際の配列から弾丸を削除してundefined
要素を削除したい場合を想像してみてください。私が考えることができる最も効率的なアルゴリズムは、弾丸を完全に一掃した後に新しい配列を作成し、削除されていないすべての弾丸をこれにコピーすることです。新しい配列。これは問題ありませんが、もっとうまくやることができます。
JavaScriptのリンクリスト!
あなたの問題に基づいて、私はあなたが以下を望んでいると思います:
一定時間の作成、反復、および削除を提供する単純なデータ構造は、リンクリストです。(とはいえ、リンクリストではランダムな弾丸をすばやく取得することはできません。それが重要な場合は、代わりにツリーを使用してください!)
では、リンクリストをどのように実装しますか?私のお気に入りの方法は、各オブジェクトにnext
参照を与えて、各箇条書きがリスト内の次の箇条書きを指すようにすることです。
初期化中
リンクリストを開始する方法は次のとおりです。
first_bullet = {
x_position: 5,
y_position: 10,
x_speed: 2,
y_speed: 10,
next_bullet: undefined, // There are no other bullets in the list yet!
};
// If there's only one bullet, the last bullet is also the first bullet.
last_bullet = first_bullet;
追加
リストの最後に箇条書きを追加するにnext
は、古いものの参照を設定してからlast_bullet
、移動しlast_bullet
ます。
new_bullet = {
x_position: 42,
y_position: 84,
x_speed: 1,
y_speed: 3,
next_bullet: undefined, // We're going to be last in the list
};
// Now the last bullet needs to point to the new bullet
last_bullet.next_bullet = new_bullet;
// And our new bullet becomes the end of the list
last_bullet = new_bullet;
反復
リンクリストを反復処理するには:
for (b = first_bullet; b; b = b.next_bullet) {
// Do whatever with the bullet b
// We want to keep track of the last bullet we saw...
// you'll see why when you have to delete a bullet
old = b;
}
削除
削除します。ここで、b
は削除される弾丸をold
表し、リンクリストでその直前の弾丸を表します---したがって、old.next_bullet
と同等b
です。
function delete_bullet(old, b) {
// Maybe we're deleting the first bullet
if (b === first_bullet) {
first_bullet = b.next_bullet;
}
// Maybe we're deleting the last one
if (b === last_bullet) {
last_bullet = old;
}
// Now bypass b in the linked list
old.next_bullet = b.next_bullet;
};
を使用して箇条書きを削除しなかったことに注意してくださいdelete b
。それdelete
はあなたが思っていることをしないからです。