【问题标题】:loop through javascript object with customized order使用自定义顺序循环遍历 javascript 对象
【发布时间】:2013-08-11 17:04:49
【问题描述】:

我一直在寻找解决问题的方法,但似乎找不到任何答案……所以我不确定这是否可能。

我有一个带有产品信息的 javascript 对象,所以它看起来是这样的(请注意,它已经按照我想要的方式排序):

var prodType = {
  '7' : {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00'},
  '212' : {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00'},
  '211' : {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00'},  
  '2' : {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00'},
  '10' : {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00'}
}

然后我循环遍历它为某个插件创建一个表,下面是我如何获取信息的示例:

for(var val in prodType) {
   console.log('pid: '+val 
   + ' pname: '+prodType[val].prodname
   + ' pcategory: '+prodType[val].prodtype 
   + ' pprice: '+prodType[val].prodprice);
}

我的问题是:我需要按产品名称排序打印,但保持 id 原样 - 就像我提供它一样,因为我正在使用 ID 进行进一步的数据库处理。所以,现在它打印:

pid: 2 pname: Sarah pcategory: Book pprice: 49.00
pid: 7 pname: Abel pcategory: Book pprice: 49.00
pid: 10 pname: Walter pcategory: Book pprice: 49.00
pid: 211 pname: Devon pcategory: Book pprice: 49.00
pid: 212 pname: Carl pcategory: Book pprice: 49.00

我需要它看起来像这样:

pid: 7 pname: Abel pcategory: Book pprice: 49.00
pid: 212 pname: Carl pcategory: Book pprice: 49.00
pid: 211 pname: Devon pcategory: Book pprice: 49.00
pid: 2 pname: Sarah pcategory: Book pprice: 49.00
pid: 10 pname: Walter pcategory: Book pprice: 49.00

有可能吗?如果是这样,怎么做?非常感谢!

更新

我尝试了@go-oleg 解决方案,结果发现它不适用于我的情况:(这是我的真实数据示例:

var prodType = {
  '211' : {'prodname' : '601A - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '212' : {'prodname' : '601B - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '214' : {'prodname' : '601C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '224' : {'prodname' : '614A - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '225' : {'prodname' : '614C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '231' : {'prodname' : '614D - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '0.00'},
  '226' : {'prodname' : '702B - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '227' : {'prodname' : '702C - Blahblah','prodtype' : 'CD-ROM', 'prodprice' : '49.00'},
  '217' : {'prodname' : 'COLL2 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '16' : {'prodname' : 'COLV - Blahblah','prodtype' : 'DVD', 'prodprice' : '100.00'},
  '119' : {'prodname' : 'UM - Blahblah','prodtype' : 'Manual', 'prodprice' : '29.00'},
  '235' : {'prodname' : 'WDS - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '208' : {'prodname' : 'WTPO1 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'},
  '195' : {'prodname' : 'WTPO2 - Blahblah','prodtype' : 'Manual', 'prodprice' : '49.00'}
}

【问题讨论】:

  • 也许将这些项目复制到一个数组中,然后对其进行排序?
  • 讨厌把这个告诉你,但它是一个对象。就 ECMA-262 而言,它根本没有被订购;甚至它已排序的事实也是特定于实现的细节。如果您想要排序,请使用数组(无论是保存键列表还是对象本身)并对其进行排序。
  • 查看此处讨论的跨浏览器问题(是的,这是delete 操作员页面,但请阅读该部分)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

标签: javascript object for-loop foreach


【解决方案1】:

JavaScript 中的对象属性没有排序,所以理想情况下,prodType 应该是一个数组。如果您无法更改prodType 的格式/结构,您可以对键进行排序,然后查找与该键关联的值:

var prodType = {
  '7' : {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00'},
  '212' : {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00'},
  '211' : {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00'},  
  '2' : {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00'},
  '10' : {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00'}
};

//`sort` will sort by the "dictionary" order and it looks like you want the opposite, so use `reverse`
Object.keys(prodType).sort().reverse().forEach( function (key) {

   console.log('pid: '+key 
   + ' pname: '+prodType[key].prodname
   + ' pcategory: '+prodType[key].prodtype 
   + ' pprice: '+prodType[key].prodprice);

} );

更新:正如@plalx 所指出的,第一次使用排序函数进行您想要的排序比使用默认排序然后反转更快:

Object.keys(prodType).sort(function(a,b) {
  return a > b ? -1 : (a === b? 0 : 1);
}).forEach( function (key) {
   console.log('pid: '+key 
   + ' pname: '+prodType[key].prodname
   + ' pcategory: '+prodType[key].prodtype 
   + ' pprice: '+prodType[key].prodprice);
} );

【讨论】:

  • +1 用于保持原始结构,如果需要,这可能是快速查找的好主意,但是sort().reverse() 效率不高,您应该改为.sort(function (a, b) { return a > b? -1 : (a === b? 0 : 1);});
  • 我喜欢你的想法——我可以将它更新为一个数组,但我只是希望我不必这样做。它适用于简单的单词,但我目前的情况出于某种原因不起作用。我会用最接近我的对象的例子来更新我的问题。谢谢!
  • @plalx:谢谢!更新了答案
  • @Fabi:您希望更新后的示例中的输出是什么样的?您想要按id 排序的输出,还是希望它以与您编写的完全相同的顺序输出。正如其他人所指出的,后者是不可能的,因为 JavaScript 不维护任何类型的 Object 属性顺序。 prodType 是如何开始生成的?
  • 我希望输出完全按照这个顺序,因为它是从数据库中预购的。我将使用@Neal 解决方案,因为就像您说的那样,这不是一项可能的任务。不过谢谢你:)
【解决方案2】:

javascript 中的对象是排序的,但它们是随机排列的,恰好您的浏览器对对象键进行排序。

我建议将 id 添加到各个对象中,然后存储在有序数组中:

var prodType = [
  {'prodname' : 'Abel','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 7},
  {'prodname' : 'Carl','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 212},
  {'prodname' : 'Devon','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 211},
  {'prodname' : 'Sarah','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 2},
  {'prodname' : 'Walter','prodtype' : 'Book', 'prodprice' : '49.00', 'id': 10}
];

那么你可以这样做:

prodType.forEach(function(el){
   console.log('pid: '+ el.id
   + ' pname: '+ el.prodname
   + ' pcategory: '+ el.prodtype 
   + ' pprice: '+ el.prodprice);
});

【讨论】:

  • 其实对象键是无序的。 stackoverflow.com/questions/5525795/…您的解决方案仍然是正确的。
  • 这让我有点困惑,因为它声明它是无序的,但是一旦我循环通过它,它是有序的??
  • 没有为键指定的no排序,甚至没有排序——已排序、未排序、插入顺序或其他。对象只是属性的集合。除此之外的任何内容都是特定于实现的。
  • @Neal:除了你现在说它们没有排序。甚至 that 都关闭了。它们可以,也可以不是,在浏览器的心血来潮。顺序/排序是未指定
  • @cHao 我写了“碰巧你的浏览器对对象键进行排序”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 2014-07-14
  • 2013-03-09
  • 2015-09-16
  • 2020-01-26
  • 1970-01-01
相关资源
最近更新 更多