Reputation: 149
I want to load an external JSON object and sort based on one or more key:value pairs. For example using the JSON below I might need to sort on category1 and then type.
I've tried array.sort()
but no matter what I throw at it my data is never sorted; It's always output in the same order as in the JSON file.
{
"books": [
{
"sku": "{1234}",
"title": "Moby Dick",
"type": "paperback",
"category1": "fiction",
"category2": "classic",
"category3": "",
"image": "",
"ctaLabel": "Learn More"
},
{
"sku": "{5678}",
"title": "1984",
"type": "hardcover",
"category1": "fiction",
"category2": "",
"category3": "",
"image": "",
"ctaLabel": "Learn More"
},
{
"sku": "{5678}",
"title": "Another Title",
"type": "paperback",
"category1": "nonfiction",
"category2": "youngadult",
"category3": "",
"image": "",
"ctaLabel": "Learn More"
}
]
}
$(function() {
$.getJSON('books.json', function (data) {
console.log(data);
var items = data.books.map(function (item) {
return item.sku + ': ' + item.title;
});
if (items.length) {
var content = '<li>' + items.join('</li><li>') + '</li>';
var list = $('<ul />').html(content);
$("#show-data").html(list);
}
});
});
Upvotes: 0
Views: 79
Reputation: 19288
Based on this answer, you can implement a multi-level sort as follows :
function multiLevelSort(arr, criteria) {
return arr.sort(function(x, y) {
return criteria.reduce(function(prev, curr) {
var dir = (curr.dir < 0) ? -1 : 1,
x_ = x[curr.prop],
y_ = y[curr.prop];
return prev || (x_ === y_ ? 0 : x_ > y_ ? dir : -dir);
}, 0);
});
}
or, with destructuring (in Node but not yet in all browsers) :
function multiLevelSort(arr, criteria) {
return arr.sort(function(x, y) {
return criteria.reduce(function(prev, {prop, dir}) {
dir = (dir < 0) ? -1 : 1;
var x_ = x[prop],
y_ = y[prop];
return prev || (x_ === y_ ? 0 : x_ > y_ ? dir : -dir);
}, 0);
});
}
where :
arr
is an array of objects, as in the question.criteria
is an array of objects of the following format :var criteria = [
{prop: "type", dir: 1}, // dir:1=ascending; dir:-1=descending
{prop: "category1", dir: 1},
{prop: "category2", dir: 1}
];
Then simply call :
multiLevelSort(myArray, myCriteria);
Like Array.prototype.sort()
, myArray
will be mutated and returned.
Upvotes: 2