Skip to content

how to sort objects by property value array length?

I have two arrays like below:

const arr = [ 4, 5 ]
const arr2 = [
{
    "id": 1
    "type":[4]
},{
    "id": 2
    "type":[4,1]
},{
    "id": 3
    "type":[4,8,3]
},{
    "id": 4
    "type":[4,5]
}
]

how to sort arr2 in this way, that:

  1. such that if the type of arr2 contains all elements in arr then those objects are at the very top of the list,

  2. when it has at least one element with arr2 then should be in the next position,

  3. and the last ones should be objects that only have one (the only one in type) listed in arr,

so, the result should be:

const arr2 = [
{
    "id": 4
    "type":[4,5]
},{
    "id": 2
    "type":[4,1]
},{
    "id": 3
    "type":[4,8,3]
},{
    "id": 1
    "type":[4]
}
]

I try to do this with js` function like below:

arr2.sort(e => e.type.includes(arr))

but it not working correctly, can omeone tell me how to sort arr2 in the provided ways? thanks for any help!

Answer

const arr = [4, 5];
const arr2 = [
  {
    id: 1,
    type: [4],
  },
  {
    id: 2,
    type: [4, 1],
  },
  {
    id: 3,
    type: [4, 8, 3],
  },
  {
    id: 4,
    type: [4, 5],
  },
];

console.log(
  arr2
    .sort((e) => -e.type.length)
    .sort((e) =>
      arr.every((aType) => e.type.includes(aType))
        ? -1
        : e.type.includes(arr)
        ? 0
        : 1,
    ),
);

First we sort the array by the length to satisfy condition (3), to have object with one element type at the end.

This pre-sorted array still needs to be sorted according to (1) and (2).

To test for (1) we look at return value of every, if it’s true we return -1 to have it at the end of the resulting array. If it’s not true, we need to test for (2).

The remaining test for (2) is simply done by another call to includes, if element is found we return 0, means it remains at the position of the pre-sorted array. If it’s not found we sort it in at the end of the array by returning 1.