Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I have the following data:

enter image description here

and I was wondering how I could sort these in a specific order.

The order needs to be: Yellow, Blue, White, Green, Red and then within those colors, it would show the smallest number first.

So in this case, the correct sorting should be: y2, y3, b0, b2, b6, w2, g7, r4

Does anyone have any ideas on how to accomplish that? I'm using underscore.js if that makes it easier.

share|improve this question
4  
What have you tried? All you need is to use Array.prototype.sort and implement your custom comparison logics - just 4 or 5 lines of code. – Yeldar Kurmangaliyev Aug 16 at 4:10
up vote 7 down vote accepted

This naively assumes that all elements have a valid color (or at least it sorts elements with an invalid color first):

arr.sort( ( a, b ) => {
    const colorOrder = ['yellow', 'blue', 'white', 'green', 'red'];

    const aColorIndex = colorOrder.indexOf( a.color );
    const bColorIndex = colorOrder.indexOf( b.color );

    if ( aColorIndex === bColorIndex )
        return a.card - b.card;

    return aColorIndex - bColorIndex;
} );

Example:

const sorted = [
    { color: 'yellow', card: '3' },
    { color: 'red',    card: '4' },
    { color: 'blue',   card: '6' },
    { color: 'white',  card: '2' },
    { color: 'blue',   card: '2' },
    { color: 'yellow', card: '2' },
    { color: 'blue',   card: '0' },
    { color: 'green',  card: '7' },
].sort( ( a, b ) => {
    const colorOrder = ['yellow', 'blue', 'white', 'green', 'red'];

    const aColorIndex = colorOrder.indexOf( a.color );
    const bColorIndex = colorOrder.indexOf( b.color );

    if ( aColorIndex === bColorIndex )
        return a.card - b.card;

    return aColorIndex - bColorIndex;
} );

// Result:
[
  { "color": "yellow", "card": "2" },
  { "color": "yellow", "card": "3" },
  { "color": "blue",   "card": "0" },
  { "color": "blue",   "card": "2" },
  { "color": "blue",   "card": "6" },
  { "color": "white",  "card": "2" },
  { "color": "green",  "card": "7" },
  { "color": "red",    "card": "4" }
]
share|improve this answer
    
Note that this code is written in ES6, which is not suitable for production if not transpiled. – Derek 朕會功夫 Aug 16 at 4:36
    
@Derek朕會功夫 Not suitable for production? I write server-side JavaScript, so I've been using these features in production for a long time without any transpiler. I'm also pretty confident that anyone using JavaScript can replace the arrow function with a regular one if they are using an obsolete engine. – Paulpro Aug 16 at 4:46
    
Thank you so much for your help. It makes sense now! – Drew Aug 16 at 4:48
    
You're welcome @Drew – Paulpro Aug 16 at 4:49
    
Well, not for client side at least. It's definitely fine for server side (if it supports ES6). Anyway the comment is intended for people who came from Google searching for answers and blindly copying the code to use in theirs. – Derek 朕會功夫 Aug 16 at 4:49

You can simply use Array.prototype.sort with your custom sorting logics:

var arr = [
  { color: "yellow", card: "3" },
  { color: "red", card: "4" },
  { color: "blue", card: "6" },
  { color: "white", card: "2" },
  { color: "blue", card: "2" },
  { color: "yellow", card: "2" },
  { color: "blue", card: "0" },
  { color: "green", card: "7" }
];

var arrSorted = arr.sort(function(a, b) {
  var colorsOrder = ["yellow", "blue", "white", "green", "red"];
  function getColorIndex(x) { 
    return colorsOrder.indexOf(x.color);
  }
  
  return (getColorIndex(a) - getColorIndex(b)) || (a.card - b.card);
});

console.log(arrSorted);

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.