[解決済み] JavaScriptにおける配列とオブジェクトの効率性
質問
私は、おそらく数千のオブジェクトを持つモデルを持っています。それらを保存し、オブジェクトのIDを取得する最も効率的な方法は何だろうと考えています。IDは長い数字です。
オプション1では、インデックスが増加する単純な配列です。オプション2では、連想配列と、違いがあれば、オブジェクトを使用します。私の質問は、単一のオブジェクトを取得する必要がある場合、どちらがより効率的であるかということですが、時々それらをループしてソートします。
オプション1:非連想型配列
var a = [{id: 29938, name: 'name1'},
{id: 32994, name: 'name1'}];
function getObject(id) {
for (var i=0; i < a.length; i++) {
if (a[i].id == id)
return a[i];
}
}
連想配列によるオプション2。
var a = []; // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
return a[id];
}
更新しました。
なるほど、2つ目の選択肢で配列を使うのは論外ですね。ということは、2つ目のオプションの宣言行は、本当はこうでなければならない。
var a = {};
配列と、idをキーとするオブジェクトのどちらが、指定されたidを持つオブジェクトを取得するのに適しているかということです。
また、リストを何度もソートしなければならない場合、答えは変わるのでしょうか?
どのように解決するのですか?
簡単に言うと 配列の方がオブジェクトより速いことがほとんどです。しかし、100%正しい解決策はありません。
アップデート2017~テストと結果
var a1 = [{id: 29938, name: 'name1'}, {id: 32994, name: 'name1'}];
var a2 = [];
a2[29938] = {id: 29938, name: 'name1'};
a2[32994] = {id: 32994, name: 'name1'};
var o = {};
o['29938'] = {id: 29938, name: 'name1'};
o['32994'] = {id: 32994, name: 'name1'};
for (var f = 0; f < 2000; f++) {
var newNo = Math.floor(Math.random()*60000+10000);
if (!o[newNo.toString()]) o[newNo.toString()] = {id: newNo, name: 'test'};
if (!a2[newNo]) a2[newNo] = {id: newNo, name: 'test' };
a1.push({id: newNo, name: 'test'});
}
元の記事 - 説明
ご質問の内容には誤解があります。
Javascriptには、連想配列はありません。配列とオブジェクトのみです。
これらは配列です。
var a1 = [1, 2, 3];
var a2 = ["a", "b", "c"];
var a3 = [];
a3[0] = "a";
a3[1] = "b";
a3[2] = "c";
これも配列です。
var a3 = [];
a3[29938] = "a";
a3[32994] = "b";
どの配列も連続したインデックスを持つので、基本的には穴のあいた配列です。穴のない配列よりも遅くなります。しかし、配列の中を手動で反復するのはさらに遅くなります(ほとんど)。
これはオブジェクトです。
var a3 = {};
a3[29938] = "a";
a3[32994] = "b";
ここでは、3つの可能性についてのパフォーマンス・テストを行います。
ルックアップ配列 vs 空の配列 vs オブジェクトのパフォーマンステスト
これらのトピックについては、Smashing Magazineで素晴らしい記事を読むことができます。 高速でメモリ効率の良いJavaScriptの書き方
関連
-
Vueの要素ツリーコントロールに破線を追加する説明
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
nullのプロパティinnerHTMLを読み取れません エラーメッセージ
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み】オブジェクトからプロパティを削除する(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 実装 サイバーパンク風ボタン
おすすめ
-
JSクロスドメインソリューション リアクト構成 リバースプロキシ
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
[解決済み】Node.js getaddrinfo ENOTFOUND
-
[解決済み] 配列の結合時に未定義のプロパティ 'push' を読み込むことができない
-
[解決済み】JavaScriptの配列でforEachが関数でない不具合
-
[解決済み】GETできない / Nodejsエラー
-
[解決済み] TypeError: $.ajax(...) is not a function?
-
[解決済み】JavaScriptエラー(Uncaught SyntaxError: Unexpected end of input)
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
フロントエンド非同期(アシンク)ソリューション(全ソリューション)