我有一个ajax调用,它返回一个非常复杂的JSON对象,我很难对它进行排序。
我的电话:
$.post('/reports-ajax',arguments, function(data) {}
回应:
{
"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
}
}
我使用标准的每个调用来检查函数并使用highcharts做一些很棒的东西,但现在我正在尝试通过net_total调用对响应进行排序,我无法弄明白。
我试过了.sort()
,但错误的是它不是一个函数。我已经阅读了一段时间,但我猜我找不到合适的结果。这看起来很有希望:Sorting an array of JavaScript objects但失败了.sort
不是函数。似乎大多数.sort
在[]数组上而不是完整对象..
非常感谢任何帮助。
答案 0 :(得分:13)
排序对象没有意义,因为对象键没有位置值。例如,这个:
{ a:1, b:2 }
和此:
{ b:2, a:1 }
是完全相同的对象。它们不仅仅是相似的,它们是相同的。
javascript本身没有任何内容可以为对象键提供任何位置值。有些人可能错误地认为:
for (var key in obj) {
按特定顺序迭代对象键。但这是错误的。您应该始终假设for .. in
循环始终以随机顺序处理对象键。
显然,如果您要编写Web浏览器,则不会实现随机数生成器来解析for .. in
循环。因此,大多数Web浏览器对for .. in
循环处理对象键的方式具有意外稳定性。
通过玩浏览器来学习javascript的开发人员可能会发现他们的浏览器按字母顺序迭代对象,或者按键添加到对象的顺序。但这完全是偶然的,不能依赖。浏览器供应商可能在将来更改此行为,而不会违反任何向后兼容性(除了由相信对象具有排序顺序的人编写的错误脚本)。更不用说不同的浏览器具有不同的javascript实现,因此不一定具有相同的对象内部键排序。
除此之外,以上所有内容都是如此。 “密钥排序顺序”在javascript中没有任何意义,观察到的任何行为仅仅是实现细节。简而言之,javascript对象没有键顺序,只是假设它是随机的。
<强>解决方案强>
现在,您真正要做的是不对对象进行排序(您不能,它没有意义)。您真正想要做的是按特定顺序处理对象属性。解决方案是简单地创建一个对象键的数组(具有排序顺序),然后使用该数组处理该对象:
// 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
}
答案 1 :(得分:6)
你所拥有的不是一个数组而且没有顺序,所以你必须将它转换成一个数组,这样你才能给它命令。
依稀:
var array = [];
$.each(data, function(key, value) {
array.push(value);
});
array.sort(function(a, b) {
return a.net_total - b.net_total;
});
正如GolezTroi在评论中指出的那样,通常以上内容会丢失每个条目存储在data
下的密钥,因此您可以在上面的第一个$.each
循环中将其添加回来,但是在这种情况下,条目已经有了密钥(如number
),所以没有必要。
或者您可以将第一个$.each
替换为$.map
:
var array = $.map(data, function(entry) {
return entry;
});
// ...and then sort etc.
......无论你喜欢什么。