faizanjehangir
faizanjehangir

Reputation: 2831

custom sort order on array of objects

I know we can define our custom sort function of array of json objects. But what if the order is neither desc nor asc. For example lets say my array looks like:

[ {
    name: 'u'
  },
  {
    name: 'n'
  },
  {
    name: 'a'
  },
  { 
    name: 'n',
  } 
]

Output should look like:

[ {
    name: 'n'
  },
  {
    name: 'n'
  },
  {
    name: 'a'
  },
  { 
    name: 'u',
  } 
]

Where all the names starting with n are sorted first and then the rest. I have tried the following custom sort function:

_sortByName(a, b){
        if (a.name === 'n'){
            return 1;
        } else if(b.name === 'n'){
            return 1;
        } else if(a.name < b.name){
            return 1;
        } else if(a.name > b.name){
            return -1;
        }
    }

But the order returned for objects is wrong. What is going wrong here?

Upvotes: 17

Views: 13472

Answers (2)

DecPK
DecPK

Reputation: 25398

1) You can use indexOf here

const dict = "nau";
var myArray = [
  {
    name: "u",
  },
  {
    name: "n",
  },
  {
    name: "a",
  },
  {
    name: "n",
  },
];

myArray.sort((a, b) => dict.indexOf(a.name) - dict.indexOf(b.name));

console.log(myArray);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

2) You can use Map here

I've added some gap/space in between two character because there can be other character that will come between them, so you can place in between them

const order = {
  n: 100,
  a: 200,
  u: 300,
};

var myArray = [
  {
    name: "u",
  },
  {
    name: "n",
  },
  {
    name: "a",
  },
  {
    name: "n",
  },
];
myArray.sort((a, b) => order[a.name] - order[b.name]);

console.log(myArray);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

nrabinowitz
nrabinowitz

Reputation: 55688

If you have an arbitrary sort order, one option is to assign the order to an array and then use indexOf:

var sortOrder = ['n', 'a', 'u'];
var myArray = [{
    name: 'u'
  },
  {
    name: 'n'
  },
  {
    name: 'a'
  },
  {
    name: 'n'
  }
];
myArray.sort(function(a, b) {
  return sortOrder.indexOf(a.name) - sortOrder.indexOf(b.name);
});

console.log(myArray);

If you have many values in either array, it might be worthwhile creating a value-index map first and then using sortOrder[a.name].

Upvotes: 45

Related Questions