Sort array of objects by given incomplete array of orders in Javascript

Viewed 171

I have an array of objects:

var items = [
   {
      "id":"sugar",
      "type": 'eatables'
   },
   {
      "id":"petrol",
      "type": 'utility'
   },
   {
      "id":"apple",
      "type": 'fruits'
   },
   {
      "id":"mango",
      "type": 'fruits'
   },
   {
      "id":"book",
      "type": 'education'
   }
];

Now I have another array of orders with the help of which I want to sort items array:

var orders = [
   {
      "id":"sugar",
      "order":5
   },
   {
      "id":"book",
      "order":1
   }
];

Now what I am trying so far in my logic is that I am putting so many loops that it is totally creating mess.

Can anyone suggest me with a short and optimized logic for this?

2 Answers

One approach could be creating one dictionary which will keep the order for every element. Also, I've iterated the whole items array to store the position for the elements that are not in the orders array.

First of all, I'll declare one array which keep the whole orders, thus one array with 1..N elements.

var orderNumbers = Array.from({length: items.length}, (_, v) => v + 1);

Then I started to create the dictionary by iterating orders array and remove orders from orderNumbers.

The last step is iterating the items array and use shift method to "pop" the first element.

The final dictionary will look like

{
  "sugar": 2,
  "book": 3,
  "petrol": 1,
  "apple": 4,
  "mango": 5
}

In this code I used one dictionary because its lookup has complexity of O(1).

var items = [ { "id":"sugar", "type": 'eatables' }, { "id":"petrol", "type": 'utility' }, { "id":"apple", "type": 'fruits' }, { "id":"mango", "type": 'fruits' }, { "id":"book", "type": 'education' } ], orders = [ { "id":"sugar", "order":2 }, { "id":"book", "order":3 } ], orderNumbers = Array.from({length: items.length}, (_, v) => v + 1);

var ordersDict = orders.reduce((acc, item) => { 
     acc[item.id] = item.order;
     
     //remove from order numbers
     let index = orderNumbers.findIndex(el => el == item.order);
     orderNumbers.splice(index, 1);
     
     return acc;
}, {});

for(let i = 0; i < items.length; i++){
  if(!ordersDict.hasOwnProperty(items[i].id)){
    ordersDict[items[i].id] = orderNumbers[0];
    orderNumbers.shift();
   }
}

//sort the array
items.sort((a,b) => ordersDict[a.id] - ordersDict[b.id]);

console.log(items);

let oorder = new Object();

orders.map(item=>{oorder[item.id]=item.order});

var new_items = [];

items.map(item=>{new_items[oorder[item.id]-1]=item});
Related