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 === 1000
status && is_approved(boolean)
is_overdue
(boolean checking withdate-fns
using 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 === 1000
is_overdue
(I am using isAfter of the date-fns which returns a boolean)status === 'DONE' && !is_approved
due_date
starting from lowest to highest (ignore the null values)is_approved === true
any 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
},
]
CodePudding user response:
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)
CodePudding user response:
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; }