I'm trying to use the Array.prototype.sort()
method to reorder an array or objects.
My array of objects may look something like (I have removed irrelevant properties from the real life scenario):
[
{
context: [
{ value: 'hover' }
]
},
{
context: []
},
{
context: [
{ value: 'active' }
]
},
{
context: [
{ value: 'large' }
]
}
]
I need to re-order the objects based on the values contained within the nested objects of the context
property.
The conditions are:
hover
value, move to the end of the arraySo the above array of 4 objects should be re-ordered from [1, 2, 3, 4]
to [2, 3, 4, 1]
I can satisfy the first condition with something like:
rules.sort((a, b) => {
return (a.context.length - b.context.length);
});
...which re-orders the array based on the number of context objects (thus satisfying the first condition), but I can't figure out how to get the second condition satisfied.
I'm able to determine if either a
or b
arrays contain a context object with a hover
value, which feels like a good start, but I'm not sure where to go from here...
rules.sort((a, b) => {
const AIsHover = a.context.some(c => c.value === 'hover');
const BIsHover = b.context.some(c => c.value === 'hover');
return (a.context.length - b.context.length);
});
Any help would be much appreciated! Thanks
You can achieve that simply by distinguishing the cases:
rules.sort((a, b) => {
if (!a.context.length && !b.context.length) {
return 0;
}
if (a.context.length && !b.context.length) {
return 1;
}
if (!a.context.length && b.context.length) {
return -1;
}
if (a.context.some(c => c.value === 'hover') && b.context.some(c => c.value === 'hover')) {
return 0;
}
if (a.context.some(c => c.value === 'hover')) {
return 1;
}
if (b.context.some(c => c.value === 'hover')) {
return -1;
}
return 0;
});