基于子对象的特定键值以排序顺序迭代 JavaScript 对象

Posted

技术标签:

【中文标题】基于子对象的特定键值以排序顺序迭代 JavaScript 对象【英文标题】:Iterating over a JavaScript object in sort order based on particular key value of a child object 【发布时间】:2011-05-01 19:16:34 【问题描述】:

短版:我正在寻找 Perl 的 javascript 等价物

for my $key ( sort  $hash$afoo cmp $hash$bfoo  keys %hash ) 
    # do something with $key

更多细节:

我有一个 JSON 对象,它由一堆其他 JSON 对象组成,这些对象彼此具有相同的属性,例如 Perl 中的哈希哈希:例如:

var peopleobj =  
    "0291" :  "Forename" : "Jeremy", "Surname" : "Dyson" ,
    "0398" :  "Forename" : "Billy", "Surname" : "Bunter" ,
    "6714" :  "Forename" : "Harry", "Surname" : "Peterson" ,
    "9080" :  "Forename" : "Barry", "Surname" : "Mainwaring"

我想按姓氏值的顺序遍历peopleobj 中的对象,例如按姓氏顺序打印出名称。纯 JavaScript 或 jQuery 解决方案将在部署它的上下文中工作。

提前感谢您宝贵的时间。

【问题讨论】:

非常感谢丹尼尔 - 这真的很有用! 只是一个细节:那个东西不叫JSON对象,而是JavaScript对象; JSON 只是 JavaScript 对象的一种表示法。 感谢您的澄清,非常感谢。正式注明! 【参考方案1】:

有趣的问题... 一个简单的 JavaScript 解决方案是基于 'Surname' 属性在单独的数组中为您的对象创建索引。像这样1

var peopleobj =  
   "0291" :  "Forename" : "Jeremy", "Surname" : "Dyson" ,
   "0398" :  "Forename" : "Billy", "Surname" : "Bunter" ,
   "6714" :  "Forename" : "Harry", "Surname" : "Peterson" ,
   "9080" :  "Forename" : "Barry", "Surname" : "Mainwaring" 
;

var index = [];

// build the index
for (var x in peopleobj) 
   index.push( 'key': x, 'Surname': peopleobj[x]['Surname'] );


// sort the index
index.sort(function (a, b)  
   var as = a['Surname'], 
       bs = b['Surname']; 

   return as == bs ? 0 : (as > bs ? 1 : -1); 
); 

现在您可以遍历您的 index 数组:

for (var i = 0; i < index.length; i++) 
   console.log(peopleobj[index[i]['key']]['Surname']);

结果(在 Firebug 控制台中测试):

Bunter
Dyson
Mainwaring
Peterson

你可能想把它包装成某种可重用的 Iterator 对象,即使它很难像 Perl 一样简洁:

// Our reusable Iterator class:
function MyIterator (o, key) 
   this.index = [];
   this.i = 0;
   this.o = o;

   for (var x in o) 
      this.index.push( 'key': x, 'order': o[x][key] );
   

   this.index.sort(function (a, b)  
      var as = a['order'], 
          bs = b['order']; 

      return as == bs ? 0 : (as > bs ? 1 : -1); 
   ); 

   this.len = this.index.length;


MyIterator.prototype.next = function () 
   return this.i < this.len ?
          this.o[this.index[this.i++]['key']] :
          null;
;

然后按如下方式使用:

// Our JavaScript object:
var peopleobj =  
   "0291" :  "Forename" : "Jeremy", "Surname" : "Dyson" ,
   "0398" :  "Forename" : "Billy", "Surname" : "Bunter" ,
   "6714" :  "Forename" : "Harry", "Surname" : "Peterson" ,
   "9080" :  "Forename" : "Barry", "Surname" : "Mainwaring" 
;

// Build the Iterator object, using the 'Surname' field:
var surnameIter = new MyIterator(peopleobj, 'Surname');

// Iterate:
var i;

while (i = surnameIter.next()) 
   console.log(i['Surname'] + ' ' + i['Forename']);

结果:

Bunter Billy
Dyson Jeremy
Mainwaring Barry
Peterson Harry

1您可能希望使用hasOwnProperty() 方法来确保属性属于您的对象,而不是从Object.prototype 继承:

for (var x in peopleobj) 
   if (peopleobj.hasOwnProperty(x)) 
      index.push( 'key': x, 'Surname': peopleobj[x]['Surname'] );
   

【讨论】:

+1。很好的答案,虽然传递给sort() 的比较函数应该返回一个数字,而不是布尔值。我建议像function (a, b) var as = a.Surname., bs = b.Surname; return as == bs ? 0 : (as &gt; bs ? 1 : -1); 这是一个很好的解决方案,感谢您的解释。我在排序函数中使用了这个加上转换后的字符串到日期,并得到了我所需要的。

以上是关于基于子对象的特定键值以排序顺序迭代 JavaScript 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从 KeyValue 管道中过滤特定值以显示在 html 表中的特定标题下 |角 6 +

仅当特定密钥对值与可迭代匹配时,才在 JSON 对象中获取多个 JSON 密钥对值

HashMap:以随机顺序迭代键值对

如何使用快速编码根据特定的排序顺序对自定义对象进行排序

Map几种实现及其简介

如何迭代无序映射特定键值?