Home > Software engineering >  Sorting an array of objects -> if key comes later in the array, change order
Sorting an array of objects -> if key comes later in the array, change order

Time:01-18

Let's say I have this array of objects:

let arrOfObjs = [
{
    "id": "unique1",
    "parentId": "unique3", // So this one is equal to arrOfObjs[2].id
    "title": "title1"
}, 
{
    "id": "unique2",
    "parentId": "unique3", // This one is also equal to arrOfObjs[2].id
    "title": "title2"
}, 
{
    "id": "unique3",
    "parentId": "",
    "title": "title3"
}
]

The situation is:

  • The id is always unique

  • The parentId is not unique. The parentId is equal to one of the ids in one of the objects

What I want to achieve:

The id should always come earlier than the parentId in the array. In the example above, the first two objects contain 'unique3' (id of the 3d object) as parentId. That shouldn't happen.

So it should be sorted like this:

let arrOfObjs = [
{
    "id": "unique3",
    "parentId": "",
    "title": "title3"
}
{
    "id": "unique2",
    "parentId": "unique3", 
    "title": "title2"
}, 
{
    "id": "unique1",
    "parentId": "unique3",
    "title": "title1"
}
]

So based on the parentId of the object, it should find the id which is equal to the parentId and when the index of the object with that id is higher, that object should come first.

It's a little bit hard to explain but I hope it's clear, let me know if you have any questions

Haven't tried anything yet, no idea how I can achieve this.

CodePudding user response:

try this:

  arrOfObjs.sort((a, b) => {
  let aIndex = arrOfObjs.findIndex(obj => obj.id === a.parentId);
  let bIndex = arrOfObjs.findIndex(obj => obj.id === b.parentId);
  return aIndex - bIndex;
});

CodePudding user response:

This comparator function should work:

  • If the parentId of a is the same as the id of b, put a after b.
  • If the id of a is the same as the parentId of b, put a before b.
  • In all other cases, leave the order unchanged.

const array = [{
    "id": "unique1",
    "parentId": "unique3",
    "title": "title1"
}, {
    "id": "unique2",
    "parentId": "unique3",
    "title": "title2"
}, {
    "id": "unique3",
    "parentId": "",
    "title": "title3"
}];

array.sort((a, b) => a.parentId === b.id ? 1 : a.id === b.parentId ? -1 : 0);

console.log(array);

CodePudding user response:

You could store the position of all idand sort by parentId.

const
    data = [{ id: "unique1", parentId: "unique3", title: "title1" }, { id: "unique2", parentId: "unique3", title: "title2" }, { id: "unique3", parentId: "", title: "title3" }],
    order = Object.fromEntries(data.map(({ id }, i) => [id, i   1]));

data.sort((a, b) => (order[a.parentId] || 0) - (order[b.parentId] || 0));

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Related