希望有人可以在这里帮助我,或者至少可以为我指明正确的方向。我花了几个小时试图进行排序,但我迷路了。
下面的代码只是模拟的,我的实际json是使用jquery通过AJAX返回的。我的问题不是排序,而是在嵌套的json对象上排序。
我正在尝试根据成本对json输出进行排序。 (从最低成本到最高成本),我的尝试失败了,因此无法排序。我不断得到“排序”是不确定的。
任何帮助将不胜感激,或者如果您能在这里指出我做错了什么,将不胜感激。
var json = '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
/*
This doesnt work and returns undefined.
json["shipping_method"]["quote"].sort(function(a, b) {
return a['cost'] > b['cost'];
});
// I found this example, but also didn't work.
custSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
const a = prop2 ? e1[prop1][prop2] : e1[prop1],
b = prop2 ? e2[prop1][prop2] : e2[prop1],
sortOrder = direction === "asc" ? 1 : -1
return (a < b) ? -sortOrder : (a > b) ? //sortOrder : 0;
};
json.sort(custSort("quote", "cost", "desc"));*/
json = JSON.parse(json);
for (var i in json["shipping_method"]) {
// EDIT:: I want the sorting to occur here if possible.
for (j in json["shipping_method"][i]["quote"]) {
//EDIT:: I want to keep this for loop, but with the results sorted by cost
console.log(json["shipping_method"][i]["quote"][j]["cost"]);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
答案 0 :(得分:3)
可以将对象展平,以便在深层对象中对其进行迭代时将父键包含在其中。在此答案编辑历史中可以找到一个较早的示例。由于诸如quote-id之类的信息不重要,因此已将其删除。
下面是一个使用Object.values
的示例,它遍历一个对象并仅返回该对象值的数组(丢弃键)。然后可以按照cost
的顺序对值进行排序。
const json = JSON.parse(getData());
for (let method in json["shipping_method"]) {
// cache
let quotes = json['shipping_method'][method]['quote']
// convert object to array and sort
let sortedQuotes = Object.values(quotes).sort((a, b)=>a.cost-b.cost);
console.log(sortedQuotes)
}
/* Dummy Data */
function getData() {
return '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
}
.as-console-wrapper {
max-height: 100vh !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
这假定需要引用ID(可能放在一行中);否则,可以使用Object.values
代替Object.entries
来简化此操作(以及其他更改)。
忽略output
函数的作用。这是一个简单的示例,它不能确保正确的单元顺序,并且还具有许多其他限制和漏洞。它仅用于说明排序后原始quote
数据仍然可用。
const data = JSON.parse(getData());
for (let method in data.shipping_method) {
output({row: method}, {class:'capitalize'})
// cache
let quotes = data.shipping_method[method].quote
let sortContent = Object.entries(quotes);
let sortedQuotes = sortContent.sort((a,b)=>a[1].cost-b[1].cost).map(i=>i[0]);
for (let quoteId of sortedQuotes){
let quoteInfo = quotes[quoteId];
output({cell: quoteInfo})
}
}
/* Dummy Data */
function getData() {
return '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
}
/* Really simple output for demo purpose */
function output(data, options={}){
if ('row' in data){
let $col = $('<td></td>', options).html(data.row)
let $row = $('<tr></tr>').append($col);
$('tbody').append( $row )
}
else if ('cell' in data){
let $row = $('<tr></tr>')
for( let key in data.cell ){
let $col = $('<td></td>', options).html(data.cell[key])
$row.append($col)
}
$('tbody').append( $row )
}
}
.capitalize {
text-transform: uppercase;
}
td {
min-width: 5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead></thead>
<tbody></tbody>
</table>
答案 1 :(得分:1)
您的对象可以具有任意数量的属性,如果将对象放入数组中,则可以选择按所需的对象属性,数字或字符串进行排序。
var item = JSON.parse(json).shipping_method.ups.quote;
使用 Object.values()获取JSON对象的值数组,然后使用 slice()方法复制JSON对象的数组,而不仅仅是参考。
var byCost = Object.values(item).slice(0);
最后,您可以对该对象数组使用排序功能。
byCost.sort(function(a,b) {return a.cost - b.cost});
var json = '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
var item = JSON.parse(json).shipping_method.ups.quote;
var byCost = Object.values(item).slice(0);
byCost.sort(function(a,b) {return a.cost - b.cost});
console.log(byCost)
答案 2 :(得分:0)
似乎您在这里未找到正确的路径...查看您发布的JSON,您应该尝试对shipping_method.ups.quote
进行排序,同样值得注意的是shipping_method.ups.quote
是一个对象,并且必须转换为数组才能调用.sort
as this method lives on the Array prototype.
这可以通过几种方式完成,但是Object.values()是其中一种方式。
答案 3 :(得分:0)
您可以尝试以下操作,
json = JSON.parse(json);
let item = json.shipping_method.ups.quote,
temp = [];
for (let key in item) {
temp.push(item[key]);
}
temp.sort((x, y) => x.cost - y.cost);
json.shipping_method.ups.quote = temp;
将对象转换为数组,然后排序;
答案 4 :(得分:0)
如我所见,您的问题是按成本对对象进行排序,因为它们的键应保持不变,
尝试一下,
var json = '{"shipping_method":{"ups":{"title":"United Parcel Service","quote":{"12":{"code":"ups.12","title":"UPS 3 Day Select","cost":117.3,"tax_class_id":"0","text":"$117.30"},"13":{"code":"ups.13","title":"UPS Next Day Air Saver","cost":242.52,"tax_class_id":"0","text":"$242.52"},"14":{"code":"ups.14","title":"UPS Next Day Air Early A.M.","cost":279.95,"tax_class_id":"0","text":"$279.95"},"03":{"code":"ups.03","title":"UPS Ground","cost":54.62,"tax_class_id":"0","text":"$54.62"},"02":{"code":"ups.02","title":"UPS 2nd Day Air","cost":177.31,"tax_class_id":"0","text":"$177.31"},"01":{"code":"ups.01","title":"UPS Next Day Air","cost":248.08,"tax_class_id":"0","text":"$248.08"}},"sort_order":"","error":""}}}';
var json = JSON.parse(json);
let data = []
for(var i in json.shipping_method.ups.quote){
data.push(json.shipping_method.ups.quote[i])
data.sort((a,b) => a.cost - b.cost);
}
这将像以前一样创建这些键
let final = {} ;
data.forEach(el => final[el.code.split('.')[1]] = el);
最后用最新的报价单更新qoute:
json.shipping_method.ups.quote = final;