[解決済み] オブジェクトのプロパティで配列からオブジェクトを削除する
2022-04-21 09:22:49
質問
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
オブジェクトのプロパティにマッチして、配列からオブジェクトを削除するには?
ネイティブのJavaScriptのみでお願いします。
削除するたびに長さが減っていくので、spliceを使うのは難しいです。 クローンやオリジナルインデックスへのスプライスを使っても、長さが減少する問題が残ります。
解決方法は?
を使用していると思います。
splice
のようなものでしょうか?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
バグを修正するために必要なのは、デクリメント
i
を次回以降に適用してください(逆方向のループもアリです)。
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
線形時間削除を避けるために、必要な配列要素を 保つ を配列上に配置します。
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
で、最新のランタイムで線形時間ルックアップを避けるには、ハッシュセットを使うことができます。
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
を、素敵な関数でラップすることができます。
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'},
{id: 'efg', name: 'em'},
{id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);
その場でやる必要がない場合、それは
Array#filter
:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
関連
-
JSアレイループと効率解析の比較
-
Vue+ElementUIによる大規模なフォームの処理例
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptのオブジェクトの配列からidでオブジェクトを検索する
-
[解決済み] オブジェクトの配列から、プロパティの値を配列として取り出す。
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
-
[解決済み】未定義のオブジェクトプロパティを検出する
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
Vueにシンプルなメモ帳機能を実装
-
vueにおけるfilterの適用シーンについて解説します。
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み】awaitは非同期関数でのみ有効です。
-
[解決済み】TypeError: Router.use() はミドルウェアの関数を要求しているが、Object を取得した。
-
Uncaught TypeError: null のプロパティ 'offsetHeight' を読み取れませんでした。
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
JavaScriptのgetElementById、getElementsByTagNam、getElementsByClassNameの違いと使い方
-
jq は html ページとデータを動的に分割する。