0

I have a nested array of objects which looks like this:

mainArray = [
   { name: 'a',age: 10, details: [ { desc: 'test1' , score: 6 }, { desc: 'testa' , score: 10 }] },
   { name: 'b',age: 20, details: [ { desc: 'test2' , score: 30 }, { desc: 'testb' , score: 34 }] },
   { name: 'c',age: 40, details: [ { desc: 'test3' , score: 40 }, { desc: 'testc' , score: 7 }] }
]

What I want to do is to sort my mainArray based on score:

  1. Firstly, I want to sort the details array in descending order(highest score first)
  2. Then sort the mainArray in descending order(highest score first)
  3. Also, there might be case where details has only one item inside the array

This is the result I want:

mainArray = [ 
   { name: 'c',age: 40, details: [ { desc: 'test3' , score: 40 }, { desc: 'testc' , score: 7 } ] }
   { name: 'b',age: 20, details: [ { desc: 'test2' , score: 34 }, { desc: 'testb' , score: 30 } ] }
   { name: 'a',age: 10, details: [ { desc: 'test1' , score: 20 }, { desc: 'testa' , score: 6 } ] }
]

What I have tried is flatten the entire main array and then sort by score. But I am looking for a more efficient solution. I'm oprn to libraries like lodash etc or vanillajs fine too

pogbamessi
  • 311
  • 3
  • 17

4 Answers4

0

Sort the inner arrays first, then the highest value will be at the first position, then sort the outer array with that:

  for(const { details } of mainArray)
    details.sort((a, b) => b.score - a.score);

 mainArray.sort((a, b) => b.details[0].score - a.details[0].score);
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

You need sort functions for both of your sorts. Then you need to call the first 1 on each details element for each array element, and finally in sorting mainArray, you need to sort based on the first score

var sortHighest = function(a,b) {
  return a.score - b.score;
}

var sortFunc = function(a,b) {
  return a.details[0].score - b.details[0].score;
}

mainArray.forEach(function(item) {
  details.sort(sortHighest);
}

mainArray.sort(sortFunc);
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
0

First go over all the objects and sort their details array:

mainArray.forEach(obj => obj.details.sort((a, b) => b.score - a.score));

Then sort the array itself by comparing the first score in the details array:

mainArray.sort((a, b) => b.details[0].score - a.details[0].score);

Example:

let mainArray = [
   { name: 'a',age: 10, details: [ { desc: 'test1' , score: 6 }, { desc: 'testa' , score: 10 }] },
   { name: 'b',age: 20, details: [ { desc: 'test2' , score: 30 }, { desc: 'testb' , score: 34 }] },
   { name: 'c',age: 40, details: [ { desc: 'test3' , score: 40 }, { desc: 'testc' , score: 7 }] }
];

mainArray.forEach(obj => obj.details.sort((a, b) => b.score - a.score));
mainArray.sort((a, b) => b.details[0].score - a.details[0].score);

console.log(mainArray);
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
0

You can user Array.sort() to accomplish this.

At first sort the mainArray.details array, after that sort the mainArray.

See the below example:

mainArray.forEach(function(elem) {
  elem.details.sort(function(a, b) {
    return b.score - a.score;
  })
})

mainArray.sort(function(a, b) {
  return b.details[0].score - a.details[0].score;
})

console.log(mainArray);
<script>
  mainArray = [
   { name: 'a',age: 10, details: [ { desc: 'test1' , score: 6 }, { desc: 'testa' , score: 10 }] },
   { name: 'b',age: 20, details: [ { desc: 'test2' , score: 30 }, { desc: 'testb' , score: 34 }] },
   { name: 'c',age: 40, details: [ { desc: 'test3' , score: 40 }, { desc: 'testc' , score: 7 }] }
]
</script>
Adnan Sharif
  • 919
  • 7
  • 17