JavaScript オブジェクト内の要素の数
-
12-09-2019 - |
質問
JavaScript オブジェクト内の要素の数を (どこかから) 取得する方法はありますか?(すなわち、定数時間計算量)。
その情報を取得するプロパティまたはメソッドが見つかりません。今のところ、コレクション全体を反復処理することしか考えられませんが、それは線形時間です。
オブジェクトのサイズに直接アクセスできないのは奇妙だと思いませんか。
編集:
私が話しているのは、 Object
オブジェクト (一般的なオブジェクトではありません):
var obj = new Object ;
解決
JS 実装はそのような値を内部的に追跡する可能性がありますが、それを取得する標準的な方法はありません。
過去には、Mozilla の Javascript 亜種によって、 規格外の __count__
, ですが、バージョン 1.8.5 で削除されました。
クロスブラウザスクリプティングの場合、プロパティを明示的に繰り返してチェックする必要があります。 hasOwnProperty()
:
function countProperties(obj) {
var count = 0;
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
++count;
}
return count;
}
ECMAScript 5 対応の実装の場合、これは次のように書くこともできます ( アビ・フラックス)
function countProperties(obj) {
return Object.keys(obj).length;
}
列挙可能でないプロパティ (配列のプロパティなど) も見逃す可能性があることに注意してください。 length
).
jQuery、Prototype、Mootools、$whatever-the-newest-hype などのフレームワークを使用している場合は、独自のコレクション API が付属しているかどうかを確認してください。これは、ネイティブ JS オブジェクトを使用するよりも問題に対する優れた解決策である可能性があります。
他のヒント
もし ビルドですでに jQuery を使用している場合は、これを実行するだけです。
$(yourObject).length
これはオブジェクトに対してうまく機能し、依存関係として jQuery をすでに持っていました。
function count(){
var c= 0;
for(var p in this) if(this.hasOwnProperty(p))++c;
return c;
}
var O={a: 1, b: 2, c: 3};
count.call(O);
私の知る限り、配列に切り替えない限り、これを確実に行う方法はありません。正直に言うと、 しません 奇妙に思えます - 配列は数えられるが、オブジェクトは数えられないというのは、私にとっては非常に簡単なことのように思えます。
おそらくあなたが得る最も近いものは次のようなものです
// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
var i = 0;
for ( var p in this ) i++;
return i;
}
alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3
しかし、これでは問題、少なくとも疑問が生じます。_length 関数自体も含め、ユーザーが作成したすべてのプロパティがカウントされます。この単純な例では、通常の関数を使用するだけでこれを回避できますが、他のスクリプトによるこれの実行を停止できるわけではありません。それであなたは何をしますか?関数のプロパティを無視しますか?
Object.prototype.length = function()
{
var i = 0;
for ( var p in this )
{
if ( 'function' == typeof this[p] ) continue;
i++;
}
return i;
}
alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2
結局のところ、オブジェクトを数えられるようにするという考えを捨てて、今やっていることを何でも行うための別の方法を考え出す必要があると思います。
数、長さ、次元の概念はオブジェクトにとってはあまり意味がありません。それが必要であるということは、私にとって配列が本当に必要であることを示唆しています。
編集:これには O(1) が必要だと私に指摘されました。私の知る限り、そのような方法は存在しません。