Home > database >  Can I sort an array of objects based on a array of subarrays?
Can I sort an array of objects based on a array of subarrays?

Time:02-23

I would ask a question regarding sorting.

Let's say I have an array of objects:

let arrayToBeSorted = [
{
  name:"name1",
  id:"id1",
},
{
  name:"name2",
  id:"id2",
},
{
  name:"name3",
  id:"id3",
},
{
  name:"name4",
  id:"id4",
},
{
  name:"name5",
  id:"id5",
},
{
  name:"name6",
  id:"id6",
}];

And Let's say I have an array of sub arrays which each one is containing IDs string like that:

let sortArray = [["id2", "id1"], ["id5"], ["id6","id3","id4"]]

What I want to do is to sort the arrayToBeSorted based on the sortArray preserving each subarrays (in order to maintain an hermetic order)

This is the wanted result:

arrayToBeSorted = [
{
  name:"name2",
  id:"id2",
},
{
  name:"name1",
  id:"id1",
},
{
  name:"name5",
  id:"id5",
},
{
  name:"name6",
  id:"id6",
},
{
  name:"name3",
  id:"id3",
},
{
  name:"name4",
  id:"id4",
}];

EDIT: I tried to:

arrayToBeSorted.sort((a,b)=> for(var i=0; i<sortArray.length;i  ) 
{
   sortArr.indexOf(a.item.id) - sortArr.indexOf(b.item.id)
});

I also thought of sorting by each array and the concat the sorted result, but no success...

Thanks!

CodePudding user response:

You seem to be overcomplicating the sort operation here. Use sort() on arrayToBeSorted and get the indexOf each array element in a flat()tened copy of sortArray:

let arrayToBeSorted = [{
  name: "name1",
  id: "id1",
}, {
  name: "name2",
  id: "id2",
}, {
  name: "name3",
  id: "id3",
}, {
  name: "name4",
  id: "id4",
}, {
  name: "name5",
  id: "id5",
}, {
  name: "name6",
  id: "id6",
}];

let sortArray = [
  ["id2", "id1"],
  ["id5"],
  ["id6", "id3", "id4"]
];

console.log(arrayToBeSorted.sort((a, b) => sortArray.flat().indexOf(a.id) - sortArray.flat().indexOf(b.id)));

CodePudding user response:

You could flat the array and build an object with wanted order and sort the array.

const
    data = [{ name: "name1", id: "id1" }, {  name: "name2", id: "id2" }, { name: "name3", id: "id3" }, { name: "name4", id: "id4" }, { name: "name5", id: "id5" }, { name: "name6", id: "id6" }],
    sortArray = [["id2", "id1"], ["id5"], ["id6", "id3", "id4"]],
    order = Object.fromEntries(sortArray.flat().map((k, i) => [k, i   1]));

data.sort((a, b) => order[a.id] - order[b.id]);

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

CodePudding user response:

You can use sort() based on a flattened sortArray using findIndex() or indexOf() as @esqew. You could also go a step further and pre-process sortArray and create an object ids as keys and indices of sortArray as values. Then the sort function would be based on the object as follows:

let arrayToBeSorted = [{
        name: "name1",
        id: "id1",
    },
    {
        name: "name2",
        id: "id2",
    },
    {
        name: "name3",
        id: "id3",
    },
    {
        name: "name4",
        id: "id4",
    },
    {
        name: "name5",
        id: "id5",
    },
    {
        name: "name6",
        id: "id6",
    }
];

let sortArray = [["id2", "id1"], ["id5"], ["id6","id3","id4"]];

const flatO = Object.fromEntries( sortArray.flat().map((id,i) => [id,i]) );

const sortedArray = arrayToBeSorted.sort((a,b) => flatO[a.id] - flatO[b.id]);

console.log( sortedArray );

NOTE: This is equivalent to @NinaScholz's solution. Saw it just after I posted this. I have upvoted both @NinaScholz's and @esqew's solutions but I would take @NinaScholz's since the flat() method including the creation of the order object execute JUST ONCE.

  • Related