Reputation: 1684
I have an array with classes (the class is called Note
), and in those classes are basic values. Two important values are the Note.Pinned
(boolean whether it's pinned or not) and Note.Modified
(a timestamp when it was last edited).
I would like to sort this array of classes by the Modified
timestamp, then reorder it that the Pinned
notes are on top of this list.
I already tried sorting the notes.
const SortedNotes = Notes.sort((a, b) => a.Modified > b.Modified);
Notes
being the array with classes.
But, then, is there a better way to rearrange this array? Or is this the only method I can use?
SortedNotes.filter(n => n.Pinned).concat(SortedNotes.filter(n => !n.Pinned));
The above would work, and I know I can use Array.prototype.partition
, so is there any other way of doing this?
Thanks
Upvotes: 0
Views: 1514
Reputation: 1684
I edited @Ja͢ck's answer to be a little more compact.
const SortedNotes = Notes.sort((a, b) => {
if (a.Pinned == b.Pinned) return a.Modified > b.Modified ? -1 : 1;
else return a.Pinned ? -1 : 1;
});
Upvotes: 0
Reputation: 173572
You can sort by multiple conditions:
const SortedNotes = Notes.sort((a, b) => {
if (a.Pinned == b.Pinned) {
if (a.Modified > b.Modified) return -1;
if (a.Modified < b.Modified) return 1;
} else {
return a.Pinned ? -1 : 1;
}
});
The missing branch of a.Pinned == b.Pinned && a.Modified == b.Modified
would return undefined
, which in turn would be interpreted as equal.
Btw, the array Notes
itself would've been modified in place, so both SortedNotes
and Notes
would exhibit the same ordering; of course, assigning to a const
variable can't hurt.
Upvotes: 1
Reputation: 10398
You can just add the pinned sorting requirement to the sort:
const arr = [{
pinned: false,
modified: 7
},
{
pinned: false,
modified: 6
},
{
pinned: true,
modified: 2
},
{
pinned: false,
modified: 4
},
{
pinned: true,
modified: 1
},
{
pinned: true,
modified: 8
},
{
pinned: false,
modified: 3
},
]
arr.sort((a, b) => {
if (a.pinned != b.pinned)
return a.pinned ? -1 : 1;
return b.modified - a.modified;
})
console.log(arr)
As long as the execution of the sort function returns the same result for the same two given parameters the sort will work fine. Knowing this, you can handle the two states where the pinned state is different and then sort by modified only if the pinned state is the same.
Upvotes: 2
Reputation: 1
Shorter, you can try
const SortedNotes = Notes.sort((a, b) => {
if (a.Pinned > b.Pinned)
return 1;
if (a.Pinned == b.Pinned)
return a.Modified > b.Modified;
return -1;
})
Upvotes: 0
Reputation: 59511
Not the best solution perhaps, but this should help you in the right direction. This sorts the array so that notes are in decending date order, with the pinned ones at the top.
Unlike other (better) answers, this has a O(2n) sorting complexity, so bear that in mind.
const notes = [
{
text: "foo",
modified: 1583337610387,
pinned: false
},
{
text: "bar",
modified: 1583337610388,
pinned: true
},
{
text: "baz",
modified: 1583337610389,
pinned: false
},
{
text: "qux",
modified: 1583337610390,
pinned: true
}
];
const sortedNotes = [...notes];
sortedNotes.sort((a, b) => a.modified > b.modified ? -1 : 1);
sortedNotes.sort((a, b) => (a.pinned === b.pinned) ? 0 : a.pinned ? -1 : 1);
console.log(sortedNotes);
Upvotes: 2