反復

2009-05-20 21 views
102

はのは、私はJavascriptを連想配列(別称、ハッシュ、別名、辞書を)持っているとしましょう:反復

var a = new Array(); 
a['b'] = 1; 
a['z'] = 1; 
a['a'] = 1; 

私はソート順にキーを反復処理することができますどのように?それが物事を簡素化するのに役立つならば、私は値を必要としない(それらはすべて数字1だけである)。

+10

なぜ新しいArray()構造体を使用していて、それをオブジェクトのように使用していますか? –

+0

@ルーク..私はこれも最初にやった、PHPの背景から来た。私は今でも学んだ:) – alex

+19

@ルーク:私は経験がないので、そうだ。答えに正しい方法を投稿できますか? – mike

答えて

121

これらを直接反復することはできませんが、すべてのキーを見つけて並べ替えることができます。

var a = new Array(); 
a['b'] = 1; 
a['z'] = 1; 
a['a'] = 1;  

function keys(obj) 
{ 
    var keys = []; 

    for(var key in obj) 
    { 
     if(obj.hasOwnProperty(key)) 
     { 
      keys.push(key); 
     } 
    } 

    return keys; 
} 

keys(a).sort(); // ["a", "b", "z"] 

しかし、変数 'a'を配列にする必要はありません。あなたは本当にただのオブジェクトとしてそれを使用していて、このようにそれを作成する必要があります。

var a = {}; 
a["key"] = "value"; 
+28

'for'ループを' obj.hasOwnProperty(key) 'にチェックインするべきです。 –

+0

私のために働いています。 –

+3

@Lalit - あなたがTorokのコメントを参照しているのなら、それはあなたが頼ることのできないオブジェクトのプロトタイプを妨害するものがないからです。 –

2

最初のforループのキーを取得してソートし、2番目のforループのソート結果を使用します。

var a = new Array(); 
a['b'] = 1; 
a['z'] = 1; 
a['a'] = 1; 

var b = []; 
for (k in a) b.push(k); 
b.sort(); 
for (var i = 0; i < b.length; ++i) alert(b[i]); 
+2

を(kのb) の配列に使用すると問題が発生します。整数で反復する –

+0

配列 'a'の現在の値を保持するために使用した' k'ではなく、配列 'b'を反復したい最後の行で恐れています。 –

+0

すべての修正をありがとう。 – pts

14

あなたも、オブジェクトにそれをプロトタイプができます

Object.prototype.iterateSorted = function(worker) 
{ 
    var keys = []; 
    for (var key in this) 
    { 
     if (this.hasOwnProperty(key)) 
      keys.push(key); 
    } 
    keys.sort(); 

    for (var i = 0; i < keys.length; i++) 
    { 
     worker(this[ keys[i] ]); 
    } 
} 

と使用方法:

var myObj = { a:1, b:2 }; 
myObj.iterateSorted(function(value) 
{ 
    alert(value); 
} 
+1

JavaScriptは大文字と小文字を区別するので、 'typeof object // undefined'のため、単語' object'を大文字にする必要があります。 –

+0

はい。それはタイプミスです: –

+0

構文の修正: 'hasOwnProperty'は関数なので、角括弧ではなく括弧が必要です。私はそのような小さな編集をすることは許されませんでした。 –

3

ありますがJavascriptオブジェクトの「キー」を直接操作する簡潔な方法はありません。それは本当にそれのために設計されていません。通常のオブジェクト(または、サンプルコードの示唆しているようにArray)よりも優れたものにデータを置くことは自由ですか?

もしそうなら、「あなたはソートされた順序でキーを反復処理したい場合、どのような辞書的なオブジェクトを使うべきですか?」と言い換えることができます。あなたは、データが通常のオブジェクトであるという事実を制御することはできません場合は、このユーティリティはあなたのフル機能の辞書に通常のオブジェクトを変換します

var a = { 
    keys : new Array(), 
    hash : new Object(), 
    set : function(key, value) { 
    if (typeof(this.hash[key]) == "undefined") { this.keys.push(key); } 
    this.hash[key] = value; 
    }, 
    get : function(key) { 
    return this.hash[key]; 
    }, 
    getSortedKeys : function() { 
    this.keys.sort(); 
    return this.keys; 
    } 
}; 

// sample use 
a.set('b',1); 
a.set('z',1); 
a.set('a',1); 
var sortedKeys = a.getSortedKeys(); 
for (var i in sortedKeys) { print(sortedKeys[i]); } 

あなたは、このようなオブジェクトを開発するかもしれません
a.importObject = function(object) { 
    for (var i in object) { this.set(i, object); } 
}; 

これは、単純化のために(再利用可能なコンストラクタ関数の代わりに)オブジェクト定義でした。いつでも編集できます。

0
<script type="text/javascript"> 
    var a = { 
     b:1, 
     z:1, 
     a:1 
    }; // your JS Object 
    var keys = []; 
    for (key in a) { 
     keys.push(key); 
    } 
    keys.sort(); 
    var i = 0; 
    var keyslen = keys.length; 
    var str = ''; 
    //SORTED KEY ITERATION 
    while (i < keyslen) { 
     str += keys[i] + '=>' + a[keys[i]] + '\n'; 
     ++i; 
    } 
    alert(str); 
    /*RESULT: 
    a=>1 
    b=>1 
    z=>1 
    */ 
</script> 
6

私はSwingley's answerに同意します。私は、これらのより精巧な解決策の多くが欠落していることは重要なポイントだと思います。連想配列のキーのみに関心があり、すべての値が '1'である場合は、単純に 'キー'を値として配列に格納します。

の代わりに:

var a = { b:1, z:1, a:1 }; 
// relatively elaborate code to retrieve the keys and sort them 

用途:

var a = [ 'b', 'z', 'a' ]; 
alert(a.sort()); 

この1つの欠点は、あなたが特定のキーが同じように簡単に設定されているかどうかを判断できないということです。その問題に対する答えは、this answerjavascript function inArrayを参照してください。提示された解決策の1つの問題は、a.hasValue('key')a['key']よりわずかに遅くなることです。それはあなたのコードでは重要ではないかもしれません。

var sorted_keys = Object.keys(a).sort() 

(注:これはでは動作しません非常に古いブラウザでは、詳細なためEcmaScript5、特にIE6、7および8に対応していない最新の

121

あなたはObject.keys組み込みメソッドを使用することができます統計、this tableを参照してください)

+5

なぜこれ以上のアップノートはありませんか? – michael667

+0

@ michael667おそらくIE 7と8が広く使われているから(不幸にも、MSに感謝します) –

+1

IE7は現在0.5%、IE8は8%です。 – molnarg

2

あなたがそれらを並べ替えるために、次にsort()アレイ法、キーを取得するためにunderscore.jsライブラリからkeys機能を使用することができます。

var sortedKeys = _.keys(dict).sort(); 
アンダースコアのソースコード内

keys機能:

// Retrieve the names of an object's properties. 
// Delegates to **ECMAScript 5**'s native `Object.keys` 
_.keys = nativeKeys || function(obj) { 
    if (obj !== Object(obj)) throw new TypeError('Invalid object'); 
    var keys = []; 
    for (var key in obj) if (_.has(obj, key)) keys.push(key); 
    return keys; 
};  

// Shortcut function for checking if an object has a given property directly 
// on itself (in other words, not on a prototype). 
_.has = function(obj, key) { 
    return hasOwnProperty.call(obj, key); 
}; 
0

var a = new Array(); 
 
a['b'] = 1; 
 
a['z'] = 1; 
 
a['a'] = 1; 
 

 

 
var keys=Object.keys(a).sort(); 
 
for(var i=0,key=keys[0];i<keys.length;key=keys[++i]){ 
 
    document.write(key+' : '+a[key]+'<br>'); 
 
}

0

私は本当に@ルーク・シェーファーのプロトタイプアイデアのように、だけでなく、彼はプロトタイプの問題について言っていることを聞きます。シンプルな関数を使うのはどうですか?

function sortKeysAndDo(obj, worker) { 
 
    var keys = Object.keys(obj); 
 
    keys.sort(); 
 
    for (var i = 0; i < keys.length; i++) { 
 
    worker(keys[i], obj[keys[i]]); 
 
    } 
 
} 
 

 
function show(key, value) { 
 
    document.write(key + ' : ' + value +'<br>'); 
 
} 
 

 
var a = new Array(); 
 
a['b'] = 1; 
 
a['z'] = 1; 
 
a['a'] = 1; 
 

 
sortKeysAndDo(a, show); 
 

 
var my_object = { 'c': 3, 'a': 1, 'b': 2 }; 
 

 
sortKeysAndDo(my_object, show);

これはプロトタイプの問題を排除し、まだオブジェクトのためのソートされたイテレータを提供しているようです。私は本当にJavaScriptの専門家ではないので、私はこのソリューションが私が逃した隠された欠陥を持っているかどうかを知りたいです。