ハッシュのキーを見つける方法は?


192

私はjavascriptオブジェクトでハッシュとしてダブルを知っていますが、キーを取得するための組み込み関数を見つけることができませんでした

var h = {a:'b',c:'d'};

私のようなものが欲しい

var k = h.keys() ; // k = ['a','c'];

関数を自分で作成して項目を反復処理し、返される配列にキーを追加するのは簡単ですが、それを行うための標準のよりクリーンな方法はありますか?

見落としがちなシンプルな組み込み機能に違いないと感じていますが、見つかりません!


私はただJavaScriptに飛び込んでいますが、この投稿はあなたを助けるかもしれません。dean.edwards.name/weblog/2006/07/enum
jason saldo 2008


1
キーから値を取得するのはどうですか?また、ハッシュ内のキーの数を取得します。
zero_cool 2016年

2017年の答え:Object.keys(H)Object.values(H)
losty

回答:


274

最新のJavaScript(ECMAScript 5)にはObject.keys、この操作の実行と呼ばれる関数があります。

var obj = { "a" : 1, "b" : 2, "c" : 3};
alert(Object.keys(obj)); // will output ["a", "b", "c"]

互換性の詳細はここにあります

上のMozillaのサイトの下位互換性のためのスニペットもあります:

if(!Object.keys) Object.keys = function(o){
   if (o !== Object(o))
      throw new TypeError('Object.keys called on non-object');
   var ret=[],p;
   for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
   return ret;
}

これはもっと自然なことではないでしょうか?if(!Object.prototype.keys) Object.prototype.keys = function() { if (this !== Object(this)) throw new TypeError('Object.keys called on non-object'); var ret = [], p; for (p in this) if (Object.prototype.hasOwnProperty.call(this, p)) ret.push(p); return ret; } var x = { a: { A: 1, B: 2, C: 3 }, b: { A: 10, B: 20 } }; alert(x.a.keys());
ekkis

2
私が理解しているObject.prototype.keysように、これkeysによりObjectのすべてのサブクラス、つまりすべてのオブジェクトが利用できるようになります。OOPを使用しようとしている場合は、おそらくこれを使用します。とにかく、これは本当にあなたの要件に依存します。
Ivan Nevostruev

1
mootoolsを使用する場合、Object.keys()はすべてのブラウザーで使用できるはずです。
thepe 09/10/12

これを角度テンプレートで使用するものはありますか?パーシャルの内部では機能しません。
Jay Shukla、

これは、コードサンプルとは別の質問として質問する必要があると思います。
Ivan Nevostruev 2013

80

クライアントブラウザーとの大きな互換性を必要とする製品コードについてObject.keysは、古いブラウザーで確実にするために、上記のIvan Nevostruevの回答をシムで提案します。ただし、ECMAの新defineProperty機能を使用して、要求された正確な機能を取得することは可能です。

ECMAScript 5以降-Object.defineProperty

ECMA5以降では、列挙できObject.defineProperty()ないプロパティを定義するために使用できます。現在の互換性はまだ望まれるべき多くを持っていますが、これは最終的にはすべてのブラウザで使用可能になるはずです。(具体的には、IE8との現在の非互換性に注意してください!)

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    var keys = [];
    for(var i in this) if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
    return keys;
  },
  enumerable: false
});

var o = {
    'a': 1,
    'b': 2
}

for (var k in o) {
    console.log(k, o[k])
}

console.log(o.keys())

# OUTPUT
# > a 1
# > b 2
# > ["a", "b"]

ただし、ECMA5はすでに追加さObject.keysれているため、次のように使用することもできます。

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    return Object.keys(this);
  },
  enumerable: false
});

元の答え

Object.prototype.keys = function ()
{
  var keys = [];
  for(var i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
}

編集:この回答はしばらくの間出回っていますので、上記はそのままにしておきます。これを読んでいる人は、以下のIvan Nevostruevの回答も読んでください。

プロトタイプ関数を非列挙型にする方法はありませんhasOwnProperty。そのため、使用しないfor-inループで常にプロトタイプ関数が表示されます。Objectのプロトタイプを拡張するのがそれほど面倒でなかったら、この答えは理想的だと私はまだ思います。


9
'hasOwnProperty'は、このオブジェクトのプロトタイプのプロパティを除外します。これは知っておくと便利です。
ijw 2009年

2
回答は受け入れられたので、実装したのですが、これは言語の組み込み関数である必要があると思います。
Pat

5
グローバル変数の作成を避けるために、「for(var i in this)...」を使用する必要があることに注意してください。
Brad G.

5
Object.prototypeを変更することは避けます-以下で説明する別のコメンターとして、これはhasOwnProperty()のチェックに注意していないスクリプトを簡単に壊す可能性があります。代わりに、あまりオブジェクト指向に適さない方法を使用します。「キー」関数がまだ存在しない場合は、それを定義します。(FirefoxとChromeはどちらも、OPが望むことを正確に実行するネイティブのkeys()関数を実装しています
-IEは実装

1
Object.prototypeに何かを追加することは悪い考えのようです。これは、次のようなすべての通常のループを壊すためです:for(var k in array){}またはfor(var k in object)とそのイディオム-欠陥があるかもしれませんが-非常に一般的です。たとえば、以下のマシューダーウィンの回答によると、それはGoogleマップを壊します。
Sam Watkins

42

あなたは使うことができます Object.keys

Object.keys(h)

3
ECMAScript 5で追加されましたが、今ではほとんどの主要ブラウザーで動作するはずです
Pat

33

JavaScriptユーティリティライブラリであるUnderscore.jsを使用できます。

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"]

まあ、@ Patは組み込み関数を探しているので、それは実際に要求されたものではありませんが、それでも興味深いライブラリであり、変更されません。Object.prototype
fresskoma

2
最近では、独自の実装を作成するよりも、これらの気の利いた小さなライブラリレットを使用する方がはるかに役立つと思います...とにかく、ほとんどの実際のプロジェクトでは、とにかくアンダースコアまたは同等のライブラリを使用しています。個人的には、Underscoreを使用します。
kumarharsh 2012

_.keys(obj).lengthキーがあるかどうかを確認します。
chovy

13

私が知る限り、これはあなたができる最高のことです...

var keys = [];
for (var k in h)keys.push(k);

2
Object.prototypeが乱されている場合も、これは機能しません。
Phil

4
Object.prototypeを「いじる」のではなく、これを使用する方が良いでしょう。Object.prototypeに何かを追加すると、すべてが壊れるように見えます。配列/オブジェクトのキーをループするのは非常に一般的なイディオムです。
Sam Watkins、

8

jQueryを使用すると、次のようなキーを取得できます。

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
var keys = [];
$.each(bobject, function(key,val){ keys.push(key); });
console.log(keys); // ["primary", "bg", "hilite"]

または:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
$.map(bobject, function(v,k){return k;});

@pimlottcに感謝


3
あなたはこのルートを移動したい場合は、あなたにも使用することがありますJQuery.map$.map(h, function(v,k) { return k; });
pimlottc

6

for / inを使用してオブジェクトのプロパティをループできるので、次のようにすることができます。

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}

4

上記の最高評価の回答を使用したかった

Object.prototype.keys = function () ...

ただし、google maps API v3と組み合わせて使用​​すると、google mapsは機能しません。

for (var key in h) ...

うまくいきます。


1

関数ではなく要素のみを取得しようとしている場合、このコードはあなたを助けることができます

this.getKeys = function() {

var keys = new Array();
for(var key in this) {

    if( typeof this[key] !== 'function') {

        keys.push(key);
    }
}
return keys;

}

これは、HashMapの実装の一部であり、キーだけが必要です。キーthisを含むハッシュマップオブジェクトです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.