Reputation: 437
Sorry for not putting the specific sort in the title but I couldn't word it properly.
I'm sorting a list of file objects that have details such as name, date uploaded and category and I need to sort it in such a way that the last uploaded file is push to the top and the rest of them aren't sorted.
So for example, if I had the list sorted from oldest to newest in descending order I still want the newest one at the top.
The lists are already sorted in terms of category, date, etc. when returned from the database so I just need to further sort it after.
It has to be done in a function that gets passed to a sort().
Upvotes: 1
Views: 65
Reputation: 386766
Array#sort
is not necessarily stable, as long as you sort just by one property as in the first result.
You need another value for moving equal (resulting with 0
) items to the right place, here with additional value of id
, which are in creation order.
var data = [{ id: 0, date: '2017-01-01' }, { id: 2, date: '2017-01-01' }, { id: 5, date: '2017-01-02' }, { id: 6, date: '2017-01-05' }, { id: 9, date: '2017-01-06' }, { id: 19, date: '2017-01-11' }, { id: 24, date: '2017-02-01' }, { id: 67, date: '2017-02-01' }, { id: 80, date: '2017-02-11' }, { id: 90, date: '2017-02-21' }, { id: 101, date: '2017-02-23' }, { id: 149, date: '2017-02-28' }, { id: 163, date: '2017-03-01' }, { id: 190, date: '2017-03-02' }, { id: 321, date: '2017-03-05' }, { id: 444, date: '2017-03-17' }],
lastDate = data[data.length - 1].date;
data.sort(function (a, b) {
return (b.date === lastDate) - (a.date === lastDate);
});
console.log(data);
data.sort(function (a, b) {
return (b.date === lastDate) - (a.date === lastDate) || a.id - b.id;
});
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution would be, to use Array#pop
for the last item and Array#unshift
for inserting at top place of the array.
var data = [{ id: 0, date: '2017-01-01' }, { id: 2, date: '2017-01-01' }, { id: 5, date: '2017-01-02' }, { id: 6, date: '2017-01-05' }, { id: 9, date: '2017-01-06' }, { id: 19, date: '2017-01-11' }, { id: 24, date: '2017-02-01' }, { id: 67, date: '2017-02-01' }, { id: 80, date: '2017-02-11' }, { id: 90, date: '2017-02-21' }, { id: 101, date: '2017-02-23' }, { id: 149, date: '2017-02-28' }, { id: 163, date: '2017-03-01' }, { id: 190, date: '2017-03-02' }, { id: 321, date: '2017-03-05' }, { id: 444, date: '2017-03-17' }];
data.unshift(data.pop());
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 8931
You can achieve this by simply compound your sorting algorithm:
sortingLabels = ["date uploaded", "category", "date"]
myArray.sort((a,b) => {
for (l of sortingLabels) {
const comparison = compare(a,b,l)
if (comparison == 0) {continue}
return comparison
}
})
Now all you have to do is implement a compare(a,b,label)
function that returns -1
,1
, or 0
based on the label
.
Note: The for loop for-of
works in ES2015+, which is most modern browsers and Node.js. However, if you need to support significantly older browsers, you might want to consider using a general for-loop
Upvotes: 0
Reputation: 851
There are a lot of solutions for this. As simplest solution you can use something like https://lodash.com/docs/4.17.4#orderBy
Upvotes: 1