简体   繁体   English

按值对对象的属性进行排序并保留值

[英]Sort object's properties by value and keep values

I have created an array of food names that has duplicate data. 我创建了一个包含重复数据的食物名称数组。 By using: 通过使用:

listFoodnames.forEach(x => {
  counts[x] = (counts[x] || 0) + 1;
});

I can count how many times each item exists in the array. 我可以计算数组中每个项目存在多少次。

Using: 使用方法:

Object.keys(counts).sort((a, b) => counts[b]-counts[a])

I can sort the items' count from greatest to lowest, however, I lose the actual count that I'd like to keep. 我可以从最大到最小对项目进行排序,但是,我丢失了想要保留的实际计数。

How can I solve this? 我该如何解决?

 $('document').ready(function() { var listFoodnames = ["Batteries", "Bread", "Milk", "Bread", "Milk", "Milk"] var counts = {}; listFoodnames.forEach(x => { counts[x] = (counts[x] || 0) + 1; }); console.log(counts) //LOGS EACH ITEM AS PROPERTY AND OCCURRENCES AS VALUE var sortedCounts = Object.keys(counts).sort((a, b) => counts[b]-counts[a]) console.log(sortedCounts) //LOSES VALUES }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

Unfortunately, object properties are not guaranteed to be ordered, per the spec. 不幸的是,根据规范,不能保证对象属性是有序的。 You might try using an array of objects instead. 您可以尝试使用对象数组代替。

Also note that reduce is more appropriate than forEach when you're combining items in an array into a single object. 还要注意,将数组中的项目组合到单个对象中时, reduceforEach更合适。

 const listFoodnames = ["Batteries", "Bread", "Milk", "Bread", "Milk", "Milk"]; const counts = Object.values( listFoodnames.reduce((a, foodName) => { if (!a[foodName]) a[foodName] = { foodName, count: 0 }; a[foodName].count++; return a; }, {}) ); counts.sort((a, b) => a.count - b.count); console.log(counts); 

Instead of 代替

var sortedCounts = Object.keys(counts).sort((a, b) => counts[b] - counts[a]);

use 采用

var sortedCounts = Object.entries(counts).sort(([keyA, a], [keyB, b]) => b - a);

Next, you could map each [key, value] entry to a new object: 接下来,您可以将每个[key, value]条目映射到一个新对象:

console.log(sortedCounts.map(([key, value]) => ({[key]: value})));

The result will look like this: 结果将如下所示:

[
  {
    "Milk": 3
  },
  {
    "Bread": 2
  },
  {
    "Batteries": 1
  }
]

Note, that it is impossible to get something like 请注意,不可能获得类似

{
  "Milk": 3,
  "Bread": 2,
  "Batteries": 1
}

to work, since object properties do not have an order. 可以正常工作,因为对象属性没有顺序。

Everyone who has replied has incorrectly said -> dictionaries are not ordered 回答的每个人都错误地说-> dictionaries are not ordered

This is actually wrong, ES6 made the spec change, and have said dictionary's are ordered. 这实际上是错误的,ES6进行了规格更改,并说字典是有序的。 Although before ES6 order was not specified, most browser did even then have an order. 尽管在未指定ES6订单之前,大多数浏览器甚至都已下订单。 The order by the way is insertion order. 顺便说一下顺序是插入顺序。 The order will also work when serialized, eg. 该订单在序列化时也将起作用,例如。 JSON.parse / JSON.stringify. JSON.parse / JSON.stringify。

So using this knowledge we can make the result into the format your after, a sorted object. 因此,利用这些知识,我们可以将结果转换为后排序的对象的格式。

example below. 下面的例子。

 var listFoodnames = ["Batteries", "Bread", "Milk", "Bread", "Milk", "Milk"] var counts = {}; listFoodnames.forEach(x => { counts[x] = (counts[x] || 0) + 1; }); console.log(counts) //LOGS EACH ITEM AS PROPERTY AND OCCURRENCES AS VALUE const sortedCount = Object.entries(counts).sort((a,b) => b[1] - a[1]). reduce((a,v) => (a[v[0]] = v[1], a), {}); console.log(sortedCount); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM