I'm trying to figure out how to sort an array of objects by whether or not the value of a property in a nested array of objects contain the value stopped. When that value exists in any nested array of object, I need the parent object to be sorted to the top, from there, I'm trying to secondarily sort that sorted list by id.
const arr = [{
id: 1,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
},
{
id: 2,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'stopped',
},
],
},
{
id: 3,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
}
]
// desired result
[{
id: 2,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'stopped',
},
],
},
{
id: 1,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
},
{
id: 3,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
}
]
arr.sort((a, b) => {
const stoppeds_in_a = a.things.map(obj => obj.status).filter(status => status === 'stopped').length
const stoppeds_in_b = b.things.map(obj => obj.status).filter(status => status === 'stopped').length
// I want that who has more 'stoppeds' occurrences first
return stoppeds_in_b - stoppeds_in_a
})
const checkStopped = (things) => things.some((el) => el.status === 'stopped');
const desired = arr.sort((a, b) => checkStopped(b.things) - checkStopped(a.things));
arr.sort((a, b) => {
if (a.things.some(thing => thing.status === "stopped")) {
return -1;
} else {
return a.id - b.id;
}
});
You simply have to sort, checking that the current object being inspected has at least one "thing" with a status "stopped", otherwise a normal numerical order.