Schema
var my_array = [
{
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
}
];
Desired Behaviour
Sort objects by title alphabetically,
unless they have a pinned status of true,
in which case move this "subset" of items to the beginning of the array,
sorted by their pinned.order value.
An example scenario would be a forum which had posts sorted by date, but also had sticky posts at the top, which were sorted by a defined order.
The original schema would, therefore, be displayed as:
[
{// i am at the top, because i have a pinned status of true and order of 0
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{// i am second from the top, because i have a pinned status of true and order of 1
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{// i follow in alphabetical order
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{// i follow in alphabetical order
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
}
]
What I've Tried
my_array.sort(function(a, b) {
return a.pinned.order.localeCompare(b.pinned.order) || a.title.localeCompare(b.title);
});
based on this answer:
https://stackoverflow.com/a/45741804
I also tried...
I thought about creating two separate arrays based on the value of pinned.status, sorting them separately, and then recombining them (as shown below), but I'm wondering if there is something more elegant?
var my_array = [
{
"title": "a",
"pinned": {
"status": "true",
"order": "1"
}
},
{
"title": "d",
"pinned": {
"status": "false",
"order": "n/a"
}
},
{
"title": "c",
"pinned": {
"status": "true",
"order": "0"
}
},
{
"title": "b",
"pinned": {
"status": "false",
"order": "n/a"
}
}
];
var my_subset = [];
for (var i = 0; i < my_array.length; i++) {
if (my_array[i].pinned.status === "true") {
// add to subset
my_subset.push(my_array[i]);
// remove from original array
my_array.splice(i, 1);
}
}
// sort "pruned" original array alphabetically
my_array.sort(function(a, b) {
return a.title.localeCompare(b.title);
});
// sort subset array by pinned.order
my_subset.sort(function(a, b) {
return a.pinned.order.localeCompare(b.pinned.order, undefined, { numeric: true });
});
// prepend subset to original array
var new_array = my_subset.concat(my_array);
// array is sorted as desired
console.log(new_array);
lodash.