0

I have an array of objects :

[{cat:A,size:2},
{cat:B,size:2},
{cat:B,size:1},
{cat:A,size:3},
{cat:C,size:5},
{cat:B,size:3}]

I'd like to sort this array first, by category, then by asc size in each category. The resulting array would be :

[{cat:A,size:2},
{cat:A,size:3},
{cat:B,size:1},
{cat:B,size:2},
{cat:B,size:3},
{cat:C,size:5}]

I am currently dividing the array in temporary subsets by cat, then sorting each of them by size and joining... But I have 100000+ values to sort and I am sure there's a better/faster way. I have underscore.js included in my project if that helps. The number of cat is dynamic ... Any suggestions?

xShirase
  • 11,975
  • 4
  • 53
  • 85
  • possible duplicate of [Underscore: sortBy() based on multiple attributes](http://stackoverflow.com/questions/16426774/underscore-sortby-based-on-multiple-attributes) – Louis Dec 18 '13 at 15:32
  • possible duplicate of [Multi-sorting in underscore](http://stackoverflow.com/questions/18222517/multi-sorting-in-underscore) – Louis Dec 18 '13 at 15:33
  • It is not a duplicate, I was just suggesting underscore. The answer below is much more valuable. – xShirase Dec 18 '13 at 17:24

2 Answers2

3

Just perform both comparisons. You don't need to compare the sizes if the categories are different.

yourArray.sort(function(e1, e2) {
  if (e1.cat < e2.cat) return -1;
  if (e1.cat > e2.cat) return 1;
  // categories must be the same, so order by size
  if (e1.size < e2.size) return -1;
  if (e1.size > e2.size) return 1;
  return 0;
});
Pointy
  • 405,095
  • 59
  • 585
  • 614
0

When the categories are equal, the order is defined by the size values.
Else, the order is defined by the categories.
See it working here: https://codepen.io/JuanLanus/pen/bGNXYBL?editors=1011
Keep in mind that it works by returning negative, zero or positive values; no need to return +1 or -1.

let catSizes = [  
  { cat: 'A', size: 2 },  
  { cat: 'B', size: 2 },  
  { cat: 'B', size: 1 },  
  { cat: 'A', size: 3 },  
  { cat: 'C', size: 5 },  
  { cat: 'B', size: 3 }  
];  

  catSizes.sort( ( a, b ) => {  
    if( a.cat === b.cat ){ return a.size - b.size }  
    return a.cat > b.cat ? 1 : -1;  
  });````
Juan Lanus
  • 2,293
  • 23
  • 18