[英]Iterate over a Javascript associative array in sorted order
假设我有一个Javascript关联数组(又名哈希,又名字典):
var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;
如何按排序顺序遍历键? 如果它有助于简化操作,我什至不需要这些值(它们全都是数字1)。
您可以使用Object.keys内置方法:
var sorted_keys = Object.keys(a).sort()
(注意:这在不支持EcmaScript5的非常旧的浏览器中不起作用,尤其是IE6、7和8。有关最新统计信息,请参见此表 )
您不能直接对其进行迭代,但是可以找到所有键,然后对其进行排序。
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";
您甚至可以将其原型化到对象上:
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的回答 ,并且我认为重要的一点是缺少许多这些更详尽的解决方案。 如果仅关注关联数组中的键,并且所有值均为“ 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的答案。 提出的解决方案的一个问题是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); }
};
为了简单起见,这是一个对象定义(而不是可重用的构造函数)。 随意编辑。
您可以使用keys
功能从underscore.js库拿到钥匙,然后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);
};
在第一个for
循环中获取键,对其for
排序,然后在第二个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]);
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>'); }
我非常喜欢@ 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专家,所以我很想知道这个解决方案是否存在我错过的隐藏缺陷。
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.