私がJavascript連想配列(別名ハッシュ、別名辞書)を持っているとしましょう:
var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;
ソートされた順序でキーを反復するにはどうすればよいですか?それが物事を単純化するのに役立つなら、私は値さえも必要としません(それらはすべてただの数1です)。
a = {};です。
私がJavascript連想配列(別名ハッシュ、別名辞書)を持っているとしましょう:
var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;
ソートされた順序でキーを反復するにはどうすればよいですか?それが物事を単純化するのに役立つなら、私は値さえも必要としません(それらはすべてただの数1です)。
a = {};です。
回答:
それらを直接反復することはできませんが、すべてのキーを見つけて並べ替えることができます。
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";
forループをチェックインする必要がありますobj.hasOwnProperty(key)。
Object.keys組み込みメソッドを使用できます。
var sorted_keys = Object.keys(a).sort()
(注:これは、ECmaScript5をサポートしていない非常に古いブラウザー、特にIE6、7、8では機能しません。最新の統計の詳細については、この表を参照してください)
if (!Object.keys) { Object.keys = function (obj) { var op, result = []; for (op in obj) { if (obj.hasOwnProperty(op) { result.push(op) } } return result }
オブジェクトにプロトタイプを作成することもできます。
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」の場合は、「キー」を値として配列に格納します。
の代わりに:
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つの欠点は、特定のキーが簡単に設定されているかどうかを判断できないことです。この問題の回答については、javascript関数inArrayに対するこの回答を参照してください。提示されたソリューションの1つの問題は、a.hasValue('key')それよりも少し遅くなることa['key']です。それはあなたのコードで重要かもしれないし、重要ではないかもしれません。
Javascriptオブジェクトの「キー」を直接操作する簡潔な方法はありません。それは本当にそのために設計されていません。データを通常のオブジェクト(またはサンプルコードが示すように配列)よりも良いものに自由に配置できますか?
もしそうなら、そしてあなたの質問を「ソートされた順序でキーを反復処理したいなら、どんな辞書のようなオブジェクトを使うべきですか?」と言い換えることができますか?次に、次のようなオブジェクトを開発します。
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); }
};
これは、単純化のために(再利用可能なコンストラクター関数ではなく)オブジェクト定義でした。自由に編集してください。
underscore.jsライブラリのkeys関数を使用してキーを取得し、次に配列メソッドを使用してキーをソートできます。sort()
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);
};
<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>
私は@ luke-schaferのプロトタイプのアイデアが本当に好きですが、プロトタイプの問題について彼が言っていることも聞いています。単純な関数の使用についてはどうですか?
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の第一人者ではないので、このソリューションに見逃した欠陥が隠されているかどうか知りたいです。