'Sorting and ordering an array with different criteria
I am trying to implement sorting and order to an array.
The challenge which I am facing is that I have 5 criteria on which to base my sorting, which are:
due_date === 1000status && is_approved(boolean)is_overdue(boolean checking withdate-fnsusing thedue_date)due_date(either null, or number)is_approved
What I would like to achieve is to create a sorting function which orders the above criteria as the following (from highest to lowest):
due_date === 1000is_overdue(I am using isAfter of the date-fns which returns a boolean)status === 'DONE' && !is_approveddue_datestarting from lowest to highest (ignore the null values)is_approved === trueany other remaining object
I was thinking of perhaps running .map method, and appending a ranking value for each of the object by checking the criteria, but there must be a way of doing this in single iteration with .sort method. I already checked other StackOverflow threads, but most of their data is relatively simple such as age, name etc.
[
{
due_date: 150000,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
{
due_date: 200000,
is_approved: true,
is_overdue: false,
status: 'DONE',
},
{
due_date: 150000,
is_approved: false,
is_overdue: false,
status: 'IN PROGRESS',
},
{
due_date: 1000,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
{
due_date: 200000,
is_approved: true,
is_overdue: false,
status: 'DONE',
},
{
due_date: null,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
]
Which I want to transform to;
[
{
due_date: 1000, // By due_date 1000 - highest ranking
is_approved: false,
is_overdue: true,
status: 'TODO',
},
{
due_date: 150000,
is_approved: false,
is_overdue: true, // Is overdue - second highest
status: 'TODO',
},
{
due_date: null,
is_approved: false,
is_overdue: true, // Is overdue - second highest
status: 'TODO',
},
{
due_date: 200000,
is_approved: false, // Is not yet approved
is_overdue: false,
status: 'DONE', // and Is DONE
},
{
due_date: 150000,
is_approved: false,
is_overdue: false,
status: 'IN PROGRESS',
},
{
due_date: 200000, // Lowest ranked
is_approved: true, // Is APPROVED approved
is_overdue: false,
status: 'DONE', // and is DONE
},
]
Solution 1:[1]
The deltas of boolean value are reversed. Theat mean if you like to sort true to top, you need to use b - a.
You could have a look to the wanted propeties and their values:
due_date === 1000(desc)is_overdue(desc)is_approved(asc)status === 'DONE' + !is_approved(sum asc)due_date === null(asc)due_date(desc)
const
data = [{ due_date: 150000, is_approved: false, is_overdue: true, status: 'TODO' }, { due_date: 200000, is_approved: true, is_overdue: false, status: 'DONE' }, { due_date: 150000, is_approved: false, is_overdue: false, status: 'IN PROGRESS' }, { due_date: 1000, is_approved: false, is_overdue: true, status: 'TODO' }, { due_date: 200000, is_approved: false, is_overdue: false, status: 'DONE' }, { due_date: null, is_approved: false, is_overdue: true, status: 'TODO' }];
data.sort((a, b) =>
(b.due_date === 1000) - (a.due_date === 1000) ||
b.is_overdue - a.is_overdue ||
a.is_approved - b.is_approved ||
(a.status === 'DONE' + !a.is_approved) - (b.status === 'DONE' + !b.is_approved) ||
(a.due_date === null) - (b.due_date === null) ||
b.due_date - a.due_date
);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution 2:[2]
You just need to define a sorting function
I've implemented the first two requirements I leave the rest to you
Probably it needs a bit of refactoring but you get the idea
const data = [
{
due_date: 150000,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
{
due_date: 200000,
is_approved: true,
is_overdue: false,
status: 'DONE',
},
{
due_date: 150000,
is_approved: false,
is_overdue: false,
status: 'IN PROGRESS',
},
{
due_date: 1000,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
{
due_date: 200000,
is_approved: true,
is_overdue: false,
status: 'DONE',
},
{
due_date: null,
is_approved: false,
is_overdue: true,
status: 'TODO',
},
]
const sortingFn = (a, b) => {
if(a.due_date === 1000){
return -1
}
if(b.due_date === 1000){
return 1
}
if(a.is_overdue){
return -1
}
if(b.is_overdue){
return 1
}
//the rest of the conditions
}
data.sort(sortingFn)
console.log(data)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | R4ncid |
