按sorting顺序遍历Javascript关联数组

比方说,我有一个Javascript关联数组(又名哈希,又名字典):

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

我如何迭代键sorting? 如果它有助于简化事情,我甚至不需要这些值(它们都只是数字1)。

你不能直接迭代它们,但你可以find所有的键,然后对它们进行sorting。

 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"] 

但是,不需要将variables“a”作为数组。 你真的只是用它作为一个对象,应该像这样创build它:

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

你可以使用Object.keys的内置方法:

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

(注意:这在不支持EcmaScript5的非常旧的浏览器中不起作用,特别是IE6,7和8.有关最新统计信息,请参阅此表 )

你甚至可以把它制作成对象:

 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); } 

我同意Swingley的回答 ,我认为这是一个重要的观点,许多这些更复杂的解决scheme都是缺失的。 如果您只关心关联数组中的键,并且所有值均为“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()); 

一个缺点是你不能确定一个特定的键是否被设置为容易。 看到这个答案 javascript函数inArray为这个问题的答案。 提出的解决scheme的一个问题是a.hasValue('key')将比a['key']稍慢。 这在你的代码中可能并不重要。

没有简明的方法来直接操作Javascript对象的“键”。 这不是真的为此devise的。 你有自由把你的数据比常规的对象(或数组,如你的示例代码所示)更好的东西?

如果是这样,如果你的问题可以改写为“如果我想按照sorting顺序迭代键,应该使用什么样的词典对象? 那么你可能会开发一个像这样的对象:

 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]); } 

如果您无法控制数据是否位于常规对象中,则该实用程序会将常规对象转换为全function字典:

 a.importObject = function(object) { for (var i in object) { this.set(i, object); } }; 

为简单起见,这是一个对象定义(而不是可重用的构造函数) 随意编辑。

获取第一个for循环中的键,对它进行sorting,在第二个for循环中使用sorting结果。

 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]); 

您可以使用underscore.js库中的keys函数获取键,然后使用sort()数组方法对它们进行sorting:

 var sortedKeys = _.keys(dict).sort(); 

下划线的源代码中的keysfunction:

 // 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> 
 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>'); } 

我真的很喜欢卢克 – 斯卡弗的原型理念,但也听到他对原型问题的看法。 怎么使用一个简单的function?

 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);