javascript 如何按嵌套值对 JSON 对象进行排序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13758467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I sort a JSON object by a nested value?
提问by Dennis Smolek
I have an ajax call that returns a JSON object that is pretty complex and I'm having a hard time sorting it.
我有一个 ajax 调用,它返回一个非常复杂的 JSON 对象,我很难对其进行排序。
My call:
我的电话:
$.post('/reports-ajax',arguments, function(data) {}
The response:
响应:
{
"10001":{
"unitname":"Fort Worth",
"discounts":{"12-02-2012":"34.810000","12-03-2012":"20.810000","12-04-2012":"27.040000"},
"gross":{"12-02-2012":"56.730000","12-03-2012":"19.350000","12-04-2012":"66.390000"},
"net":{"12-02-2012":"61.920000","12-03-2012":"98.540000","12-04-2012":"39.350000"},
"discounts_total":82.66,
"gross_total":82.47,
"net_total":99.81,
"number":10001
},
"10002":{
"unitname":"Dallast",
"discounts":{"12-02-2012":"12.600000","12-03-2012":"25.780000","12-04-2012":"47.780000","12-05-2012":"45.210000"},
"gross":{"12-02-2012":"29.370000","12-03-2012":"91.110000","12-04-2012":"60.890000","12-05-2012":"51.870000"},
"net":{"12-02-2012":"16.770000","12-03-2012":"65.330000","12-04-2012":"13.110000","12-05-2012":"06.660000"},
"discounts_total":131.37,
"gross_total":33.24,
"net_total":101.87,
"number":10002
},
"32402":{
"unitname":"Austin",
"discounts":{"12-05-2012":"52.890000","12-02-2012":"22.430000","12-03-2012":"58.420000","12-04-2012":"53.130000"},
"gross":{"12-05-2012":"25.020000","12-02-2012":"2836.010000","12-03-2012":"54.740000","12-04-2012":"45.330000"},
"net":{"12-04-2012":"92.200000","12-05-2012":"72.130000","12-02-2012":"13.580000","12-03-2012":"96.320000"},
"discounts_total":186.87,
"gross_total":161.1,
"net_total":174.23,
"number":32402
}
}
I go over the function with a standard each call and do some awesome stuff with highcharts but now I'm trying to sort the responses by the net_total call and I can't figure it out.
我每次调用都使用标准检查函数,并使用 highcharts 做一些很棒的事情,但现在我试图通过 net_total 调用对响应进行排序,但我无法弄清楚。
I tried .sort()
and it errors out that its not a function. I've been reading for a while but guess I'm not finding the right results. This looked promising: Sorting an array of JavaScript objectsbut it failed with the .sort
is not a function. It seems most .sort
are on [] arrays not full objects..
我试过了.sort()
,它错误地指出它不是一个函数。我已经阅读了一段时间,但我想我没有找到正确的结果。这看起来很有希望:对 JavaScript 对象数组进行排序,但它失败了,.sort
因为不是函数。似乎大多数.sort
都在 [] 数组上而不是完整的对象上。
Any help would be greatly appreciated.
任何帮助将不胜感激。
回答by slebetman
Sorting objects doesn't make sense since object keys have no positional value. For example, this:
排序对象没有意义,因为对象键没有位置值。例如,这个:
{ a:1, b:2 }
and this:
还有这个:
{ b:2, a:1 }
are exactly the same object. They're not just similar, they're the same.
是完全相同的对象。它们不仅相似,而且是相同的。
Nothing in javascript per se gives object keys any positional value. Some people perhaps are mistaken in the belief that:
javascript 本身没有任何内容为对象键提供任何位置值。有些人可能错误地认为:
for (var key in obj) {
iterates through the object keys in a specific sequence. But this is wrong. You should always assume that the for .. in
loop processes object keys in random order, always, all the time.
以特定顺序遍历对象键。但这是错误的。您应该始终假设for .. in
循环始终以随机顺序处理对象键。
Obviously, if you're going to write a web browser, you're not going to implement a random number generator to parse a for .. in
loop. Therefore most web browsers have an accidentalstability to how the for .. in
loop processes object keys.
显然,如果您要编写 Web 浏览器,则不会实现随机数生成器来解析for .. in
循环。因此,大多数 Web 浏览器对循环处理对象键的方式具有偶然的稳定性for .. in
。
Developers who learn javascript by playing around with the browser may figure out that their browser iterates through objects in alphabetical order for example, or the order the keys were added to the object. But this is totally accidental and cannot be relied upon. The browser vendor may change this behavior in the future without violating any backwards compatability (except with buggy scripts written by people who believe objects have a sort order). Not to mention that different browsers have different implementations of javascript and therefore not necessarily have the same internal key ordering of objects.
通过玩转浏览器来学习 javascript 的开发人员可能会发现他们的浏览器按字母顺序遍历对象,或者键添加到对象的顺序。但这完全是偶然的,不能依赖。浏览器供应商将来可能会在不违反任何向后兼容性的情况下更改此行为(除非由相信对象具有排序顺序的人编写的错误脚本除外)。更不用说不同的浏览器具有不同的 javascript 实现,因此不一定具有相同的对象内部键顺序。
All the above is besides the point. "Key sort order" does not make any sense in javascript and any behavior observed is merely implementation detail. In short, javascript object does not have key order, just assume it's random.
以上都是题外话。“键排序顺序”在 javascript 中没有任何意义,观察到的任何行为仅仅是实现细节。简而言之,javascript 对象没有键顺序,只是假设它是随机的。
Solution
解决方案
Now, what you're really trying to do is notsort the object (you can't, it doesn't make sense). What you're really trying to do is process the object attributes in a specific order. The solution is to simply create an array (which has sorting order) of object keys and then process the object using that array:
现在,你真正想做的不是对对象进行排序(你不能,这没有意义)。您真正想做的是按特定顺序处理对象属性。解决方案是简单地创建一个对象键的数组(具有排序顺序),然后使用该数组处理对象:
// First create the array of keys/net_total so that we can sort it:
var sort_array = [];
for (var key in Response) {
sort_array.push({key:key,net_total:Response[key].net_total});
}
// Now sort it:
sort_array.sort(function(x,y){return x.net_total - y.net_total});
// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
var item = Response[sort_array[i].key];
// now do stuff with each item
}
回答by T.J. Crowder
What you have there isn't an array and has no order, so you'll have to transform it into an array so you can give it order.
你所拥有的不是一个数组,也没有顺序,所以你必须将它转换成一个数组,这样你才能给它排序。
Vaguely:
依稀:
var array = [];
$.each(data, function(key, value) {
array.push(value);
});
array.sort(function(a, b) {
return a.net_total - b.net_total;
});
As GolezTroi points out in the comments, normally the above would lose the key that each entry is stored under in data
and so you'd add it back in the first $.each
loop above, but in this case the entries already have the key on them (as number
), so there's no need.
正如 GolezTroi 在评论中指出的那样,通常上面的内容会丢失每个条目存储在其中的键,data
因此您可以将其添加回$.each
上面的第一个循环中,但在这种情况下,条目上已经有了键(如number
),所以没有必要。
Or you can replace the first $.each
with $.map
:
或者你也可以在第一替换$.each
用$.map
:
var array = $.map(data, function(entry) {
return entry;
});
// ...and then sort etc.
...whichever you prefer.
……你喜欢哪个。