Sort an Array of Object by a Property (With Custom Order, Not Alphabetically)

Sort an array of object by a property (with custom order, not alphabetically)

You could take an object for the wanted order.

var array = [{ code: "RED", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }, { code: "RED", value: 0 }, { code: "GREEN", value: 0 }, { code: "BLUE", value: 0 }],
order = { GREEN: 1, BLUE: 2, RED: 3 };

array.sort(function (a, b) {
return order[a.code] - order[b.code];
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sort array of objects by string property value

It's easy enough to write your own comparison function:

function compare( a, b ) {
if ( a.last_nom < b.last_nom ){
return -1;
}
if ( a.last_nom > b.last_nom ){
return 1;
}
return 0;
}

objs.sort( compare );

Or inline (c/o Marco Demaio):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

Or simplified for numeric (c/o Andre Figueiredo):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

Sorting an array of objects by property values

Sort homes by price in ascending order:

homes.sort(function(a, b) {
return parseFloat(a.price) - parseFloat(b.price);
});

Or after ES6 version:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Some documentation can be found here.

For descending order, you may use

homes.sort((a, b) => parseFloat(b.price) - parseFloat(a.price));

Custom sort array to order object based on string - Javascript

You need to specify priority array first.

var priority = [ "mv", "b", "fw"];

Now sort your array based on this as

arr.sort( ( a, b ) => priority.indexOf( a.position ) - priority.indexOf( b.position ) );

Demo

var arr = [{    "name": "Ricard Blidstrand",    "number": "5",    "position": "b"  },  {    "name": "Gustaf Thorell",    "number": "12",    "position": "fw"  },  {    "name": "Rasmus Bengtsson",    "number": "13",    "position": "mv"  }];
var priority = [ "mv", "b", "fw"];
arr.sort( ( a, b ) => priority.indexOf( a.position ) - priority.indexOf( b.position ) );
console.log(arr);

Sort array of objects by text (not alphabetically -, 'easiest' to 'hardest')

I would suggest you to use a map from string to int:

const sortMap = {
'easiest': 0,
'easy': 1,
'medium': 2,
'hard': 3,
'hardest': 4,
}
// and then sort with it
items.sort((a, b) => (sortMap[b.difficulty] - sortMap[a.difficulty]);

This might be a bit more faster then using indexOf, but it's a bit error prone, since you have to be cautious assigning the values to the key in the map object

Javascript Sorting Array in custom order

You can compare y after each time you compare x:

var message = [
{type:"Error", message:"This is an Error"},
{type:"Info", message:"This is an Info"},
{type:"Warning", message:"This is a Warning"}
];

function myFunction() {
message.sort(function(a, b){
var x = a.type.toLowerCase();
var y = b.type.toLowerCase();
if (x === 'error') {return -1;}
else if(y === 'error'){return 1;}
else if (x === 'warning') {return -1;}
else if (y === 'warning') {return 1;}
else if (x === 'info') {return -1;}
else if (y === 'info') {return 1;}
return 0;
});
}

myFunction();
console.log(message);

Applying custom sorting to array of objects in typescript

Explanation:
Since you asked for a description, I'm trying my best to explain it as simple as possible first:
The sort function you apply to an array generally expects two arguments to be compared directly and returns a number. This number can be seen as "smaller than" (negative), "greater than" (positive) or "equals" (zero). Therefore, the function will be called multiple times in your case. In theory, it's also possible to not have these two arguments, e.g. for a random order you could write: cars.sort(() => Math.random() - 0.5)

So, any function that returns a number can be used in order to sort an array. In your case it would be:

Sorting by defined hierachy of categories / use ID in case of same category:

const cars: { id: number; category: string }[] = [
{ id: 3, category: "fast car" },
{ id: 0, category: "fast car" },
{ id: 1, category: "slow car" },
{ id: 2, category: "fast car" }
];

const orderCategory = { 'fast car': 1, 'slow car': 2 };

cars.sort((carA, carB) => {
if (carA.category !== carB.category) {
return orderCategory[carA.category] - orderCategory[carB.category];
} else {
return carA.id - carB.id;
}
});

console.log(cars);

Two other advices:

  • You can use const instead of let in your case
  • You do not have to use quotation marks for id and category

I hope my explanation could help you! Happy coding


EDIT: Formatted code.


EDIT 2: I just saw that you wanted fast cars to be listed at first. In my previous implementation, this worked because of the alphabetical order (F < S). But if the alphabetical order is not the reason why you want them to be listed at first, you'll have to define categories. You could now rename "fast car" to "sports car" (everywhere) and the respective cars would be listed at first, whereas they would have been below each "slow car" based on the alphabetical sorting.

I just updated the code above. This is the old implementation based on the alphabetical order:

Alphabetical sorting of categories / use ID in case of same category:

cars.sort((carA, carB) => {
if (carA.category < carB.category) {
return -1;
} else if (carA.category > carB.category) {
return 1;
}
// same as: else if (carA.category === carB.category)
else {
return carA.id - carB.id;
}
});

EDIT 3: Adjusted random sorting example in my explanation. Math.random() returns a number between 0 and 1. Thus, I substracted 0.5 in order to randomly return a negative number.



Related Topics



Leave a reply



Submit