0

I have the following object:

const obj = {
  A: [{
    capacity: 100
  }, {
    capacity: 100
  }, {
    capacity: 100
  }],
  B: [{
    capacity: 500
  }, {
    capacity: 500
  }, {
    capacity: 500
  }],
  C: [{
    capacity: 300
  }, {
    capacity: 300
  }, {
    capacity: 300
  }]
}

I need to transform to an object with the same shape but with the keys sorted by capacity. To note, the capacity of each object in the arrays (A, B, C) is always the same within the same object. So we can take the first occurrence for example

Expected result:

const obj = {
  A: [{
    capacity: 100
  }, {
    capacity: 100
  }, {
    capacity: 100
  }],
  C: [{
    capacity: 300
  }, {
    capacity: 300
  }, {
    capacity: 300
  }],
  B: [{
    capacity: 500
  }, {
    capacity: 500
  }, {
    capacity: 500
  }]
}

None of my approaches worked out. An example:

const sortByPosition = obj => {
   const order = [], res = {};
   Object.keys(obj).forEach(key => {
      return order[obj[key][1]['capacity'] - 1] = key;
   });
   order.forEach(key => {
      res[key] = obj[key];
   });
   return res;
}

console.log(sortByPosition(obj));

Here's a fiddle

SixtyEight
  • 2,220
  • 3
  • 14
  • 25

3 Answers3

2

const obj = {
  A: [ { capacity: 100 }, { capacity: 100 }, { capacity: 100 } ],
  B: [ { capacity: 500 }, { capacity: 500 }, { capacity: 500 } ],
  C: [ { capacity: 300 }, { capacity: 300 }, { capacity: 300 } ]
};

console.log(Object.fromEntries(Object.entries(obj)
  .sort(([i,a],[j,b])=>a[0].capacity-b[0].capacity)));
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
1

There are several methods to solve your problem, here is the best understandable one:

const sortByPosition = obj => {
  let sortable = [];
  let objSorted = {};
  
  for (let key in obj) {
      sortable.push([key, obj[key]]);
  }

  sortable.sort(function(a, b) {
      return a[1][0].capacity - b[1][0].capacity;
  });
  
  
  sortable.forEach(function(item){
      objSorted[item[0]] = item[1]
  })
  
  return objSorted;
}

console.log(sortByPosition(obj));
console.log(Object.keys(sortByPosition(obj)));
console.log(Object.keys(obj));

I printed 3 logs in my code. In the result of first log, it seems to be no change. But from the 2nd and 3rd logs, we can see that the result is correct. Those logs are follows:

["A", "C", "B"]
["A", "B", "C"]
talent-jsdev
  • 656
  • 4
  • 14
1

I would like to point out that objects in javascript cannot be sorted, here is a good answer that shows you the mechanism under the hood https://stackoverflow.com/a/23202095/4099454

To achieve your sorting, I'd suggest you to go for a different data structure, such as a Pair[] (a list of tuples where the key is the first item, and the capacity list the second):

const obj = {
  A: [ { capacity: 100 }, { capacity: 100 }, { capacity: 100 } ],
  B: [ { capacity: 500 }, { capacity: 500 }, { capacity: 500 } ],
  C: [ { capacity: 300 }, { capacity: 300 }, { capacity: 300 } ]
};

const pairs = Object.entries(obj);

// You'd also have to settle on the sorting algorithm, but
// let's just take the first capacity for the sake of this example
const toSortable = ([, capacities]) => capacities[0]?.capacity;

const sort = (list) => list.slice().sort(
  (left, right) => toSortable(left) - toSortable(right),
);

console.log(
  sort(pairs),
);
Hitmands
  • 13,491
  • 4
  • 34
  • 69