Home > Net >  Sorting objects but maintaining tied values
Sorting objects but maintaining tied values

Time:11-22

I have an array of objects that need to be sorted into a list but I'd like to group tied values. The array is essentially:

var sorted = [
    {
        section:"Red",
        score:12
    },
    {
        section:"Green",
        score:12
    },
    {
        section:"Blue",
        score:9
    },
...
]

And the result I am aiming for would be to output something along the lines of Your first choices are Red and Green, your second choice is Blue, your third choices are...

I've sorted the main array already to sort the objects in an ascending order, but don't really know how to address the objects that have the same score.

I have been trying to get this to work https://www.tutorialspoint.com/sort-the-array-and-group-all-the-identical-duplicate-numbers-into-their-separate-subarray-in-javascript but I can't quite figure it out to adapt to my situation. This doesn't quite work but I am getting close. It seems to be missing the first result...

var sorted = [
    {
        section:"Red",
        score:12
    },
    {
        section:"Green",
        score:12
    },
    {
        section:"Blue",
        score:9
    },
    {
        section:"Yellow",
        score:8
    },
    {
        section:"Grey",
        score:6
    },
    {
        section:"Black",
        score:6
    }
]
const sortAndGroup = (sorted = []) => {
   let result = [];
   let groupArray = [];
   for (let i = 1; i < sorted.length; i  ) {
      if (sorted[i - 1].score !== sorted[i].score) {
         groupArray = [];
         result.push(groupArray);
      };
      groupArray.push(sorted[i].section   ", "   sorted[i].score);
   };
   return result;
};
console.log(sortAndGroup(sorted));

CodePudding user response:

Using reduce() we can combine the grouping with the sorting.

If we use the number score as index of our result array from reduce(), we only need to remove the undefined's from the array to end up with a sorted list of objects

var data = [
    { section:"Blue",   score:9  },
    { section:"Yellow", score:8  }, 
    { section:"Red",    score:12 },
    { section:"Purple", score: 1 },
    { section:"Green",  score:12 },
    { section:"Grey",   score:6  },
    { section:"Black",  score:6  }
]

let result = data.reduce((a, c) => {
    if (!a[c.score]) a[c.score] = { score: c.score, options: [ ]};
    a[c.score].options.push(c.section)
    return a
}, []).filter(Boolean);

result.forEach(({ score, options }, i) => {
    console.log(`${i   1} --> Score: ${score}\tOptions: ${options.join(', ')}`); 
});

1 --> Score: 1  Options: Purple
2 --> Score: 6  Options: Grey, Black
3 --> Score: 8  Options: Yellow
4 --> Score: 9  Options: Blue
5 --> Score: 12 Options: Red, Green
  • Related