4

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.

1
  • 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. Commented Aug 16, 2016 at 4:10

2 Answers 2

17

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" }
]
Sign up to request clarification or add additional context in comments.

6 Comments

Note that this code is written in ES6, which is not suitable for production if not transpiled.
@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.
Thank you so much for your help. It makes sense now!
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朕會功夫 Okay, the comment is fair and helpful :) I assumed you were the downvoter as well; sorry if that was an incorrect assumption.
|
3

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.