-3

I have a project where I receive a list of products which I then group by the manufacturer. I want to programmatically display these on the page, but need to do so in the order of most to least products. I need to come up with an algorithm to sort the object keys from most products to least products.

Here is a simplified example of what I have, and where I need to get to:

let devices = {
  Sony: [
    {name: 'Experia 1', productCode: 's1'}, 
    {name: 'Experia 2', productCode: 's2'}
  ],
  Apple: [
    {name: 'iPhone 8', productCode: 'a1'}, 
    {name: 'iPhone 9', productCode: 'a2'}, 
    {name: 'iPhone 10', productCode: 'a3'}, 
    {name: 'iPhone 11', productCode: 'a4'}
  ],
  Huawei : [
    {name: 'S 21', productCode: 'h1'}
  ],
  LG: [
    {name: 'V60', productCode: 'l1'},
    {name: 'V60 Ultra', productCode: 'l2'},
    {name: 'G7', productCode: 'l3'}
  ]
}

I need to order the data so it starts with the manufacturer with the most is first then descends to the manufacturer with the least. So it needs to be modified to look like this:

{
  Apple: [
    {name: 'iPhone 8', productCode: 'a1'}, 
    {name: 'iPhone 9', productCode: 'a2'}, 
    {name: 'iPhone 10', productCode: 'a3'}, 
    {name: 'iPhone 11', productCode: 'a4'}
  ],
  LG: [
    {name: 'V60', productCode: 'l1'},
    {name: 'V60 Ultra', productCode: 'l2'},
    {name: 'G7', productCode: 'l3'}
  ]
  Sony: [
    {name: 'Experia 1', productCode: 's1'}, 
    {name: 'Experia 2', productCode: 's2'}
  ],
  Huawei : [
    {name: 'S 21', productCode: 'h1'}
  ],
}

The devices on offer will differ frequently, so I need to sort this data every time the user accesses the page. Because of that I'm looking for the shortest possible syntax to achieve this.

I am finding tutorials on how to sort object keys alphabetically, and other similarly related algorithms, but not one that does exactly this. I've started trying to customize some basic sorting algorithms, but data manipulation is not my strong suit, so they are either failing or turning into a bloated spaghetti code mess.

Is there a short and easy way to convert the data as described? Perhaps there is a sorting method or design pattern that is particularly well suited to the task. I've been looking into lodash commands, but am not finding anything that immediately jumps out as a solution.

I'd be very grateful for any advice that anyone could offer. Thank you in advance

jabaa
  • 5,844
  • 3
  • 9
  • 30
phunder
  • 1,607
  • 3
  • 17
  • 33
  • why not take an array? this is made for ordered item. – Nina Scholz Mar 09 '22 at 15:43
  • Seems odd you want to order the object. It probably be better to order it when you are displaying the data. How are you using this data? – epascarello Mar 09 '22 at 16:03
  • @epascarello I need to display the data in order of manufacturer with the most devices descending to the least devices, hence the ordered requirement. – phunder Mar 10 '22 at 07:42
  • @NinaScholz I have considered using a two-dimensional array, so if it is easier doing so that would work fine. – phunder Mar 10 '22 at 07:43

1 Answers1

5

You can convert it to an array, sort it by the length, and convert it back into an object.

let devices = {
  Sony: [
    {name: 'Experia 1', productCode: 's1'}, 
    {name: 'Experia 2', productCode: 's2'}
  ],
  Apple: [
    {name: 'iPhone 8', productCode: 'a1'}, 
    {name: 'iPhone 9', productCode: 'a2'}, 
    {name: 'iPhone 10', productCode: 'a3'}, 
    {name: 'iPhone 11', productCode: 'a4'}
  ],
  Huawei : [
    {name: 'S 21', productCode: 'h1'}
  ],
  LG: [
    {name: 'V60', productCode: 'l1'},
    {name: 'V60 Ultra', productCode: 'l2'},
    {name: 'G7', productCode: 'l3'}
  ]
}

devices = Object.fromEntries(Object.entries(devices).sort( (a,b) => b[1].length - a[1].length));

console.log(devices)

If you are looping over the object, I would not convert it back to an object, I would just use Object.entries and output my data based on that.

epascarello
  • 204,599
  • 20
  • 195
  • 236