Sorting objects by property values
Solution 1
javascript has the sort function which can take another function as parameter - that second function is used to compare two elements.
Example:
cars = [
{
name: "Honda",
speed: 80
},
{
name: "BMW",
speed: 180
},
{
name: "Trabi",
speed: 40
},
{
name: "Ferrari",
speed: 200
}
]
cars.sort(function(a, b) {
return a.speed - b.speed;
})
for(var i in cars)
document.writeln(cars[i].name) // Trabi Honda BMW Ferrari
ok, from your comment i see that you're using the word 'sort' in a wrong sense. In programming "sort" means "put things in a certain order", not "arrange things in groups". The latter is much simpler - this is just how you "sort" things in the real world
- make two empty arrays ("boxes")
- for each object in your list, check if it matches the criteria
- if yes, put it in the first "box"
- if no, put it in the second "box"
Solution 2
Example.
This runs on cscript.exe, on windows.
// define the Car class
(function() {
// makeClass - By John Resig (MIT Licensed)
// Allows either new User() or User() to be employed for construction.
function makeClass(){
return function(args){
if ( this instanceof arguments.callee ) {
if ( typeof this.init == "function" )
this.init.apply( this, (args && args.callee) ? args : arguments );
} else
return new arguments.callee( arguments );
};
}
Car = makeClass();
Car.prototype.init = function(make, model, price, topSpeed, weight) {
this.make = make;
this.model = model;
this.price = price;
this.weight = weight;
this.topSpeed = topSpeed;
};
})();
// create a list of cars
var autos = [
new Car("Chevy", "Corvair", 1800, 88, 2900),
new Car("Buick", "LeSabre", 31000, 138, 3700),
new Car("Toyota", "Prius", 24000, 103, 3200),
new Car("Porsche", "911", 92000, 155, 3100),
new Car("Mercedes", "E500", 67000, 145, 3800),
new Car("VW", "Passat", 31000, 135, 3700)
];
// a list of sorting functions
var sorters = {
byWeight : function(a,b) {
return (a.weight - b.weight);
},
bySpeed : function(a,b) {
return (a.topSpeed - b.topSpeed);
},
byPrice : function(a,b) {
return (a.price - b.price);
},
byModelName : function(a,b) {
return ((a.model < b.model) ? -1 : ((a.model > b.model) ? 1 : 0));
},
byMake : function(a,b) {
return ((a.make < b.make) ? -1 : ((a.make > b.make) ? 1 : 0));
}
};
function say(s) {WScript.Echo(s);}
function show(title)
{
say ("sorted by: "+title);
for (var i=0; i < autos.length; i++) {
say(" " + autos[i].model);
}
say(" ");
}
autos.sort(sorters.byWeight);
show("Weight");
autos.sort(sorters.byModelName);
show("Name");
autos.sort(sorters.byPrice);
show("Price");
You can also make a general sorter.
var byProperty = function(prop) {
return function(a,b) {
if (typeof a[prop] == "number") {
return (a[prop] - b[prop]);
} else {
return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
}
};
};
autos.sort(byProperty("topSpeed"));
show("Top Speed");
Solution 3
I have wrote this simple function for myself:
function sortObj(list, key) {
function compare(a, b) {
a = a[key];
b = b[key];
var type = (typeof(a) === 'string' ||
typeof(b) === 'string') ? 'string' : 'number';
var result;
if (type === 'string') result = a.localeCompare(b);
else result = a - b;
return result;
}
return list.sort(compare);
}
for example you have list of cars:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Solution 4
Here's a short example, that creates and array of objects, and sorts numerically or alphabetically:
// Create Objects Array
var arrayCarObjects = [
{brand: "Honda", topSpeed: 45},
{brand: "Ford", topSpeed: 6},
{brand: "Toyota", topSpeed: 240},
{brand: "Chevrolet", topSpeed: 120},
{brand: "Ferrari", topSpeed: 1000}
];
// Sort Objects Numerically
arrayCarObjects.sort((a, b) => (a.topSpeed - b.topSpeed));
// Sort Objects Alphabetically
arrayCarObjects.sort((a, b) => (a.brand > b.brand) ? 1 : -1);
Solution 5
Let us say we have to sort a list of objects in ascending order based on a particular property, in this example lets say we have to sort based on the "name" property, then below is the required code :
var list_Objects = [{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}];
Console.log(list_Objects); //[{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}]
list_Objects.sort(function(a,b){
return a["name"].localeCompare(b["name"]);
});
Console.log(list_Objects); //[{"name"="Abhi"},{"name"="Bob"},{"name"="Jay"}]
Related videos on Youtube
Constructor
Updated on July 08, 2022Comments
-
Constructor almost 2 years
How to implement the following scenario using Javascript only:
- Create a car object with properties (top speed, brand, etc.)
- Sort a list of cars ordered by those properties
-
Christian C. Salvadó about 14 years@durilai: JavaScript is object oriented, the OO model of JavaScript is based on Prototyping and is really, really versatile... en.wikipedia.org/wiki/Prototype-based_programming
-
Chemical Programmer over 8 yearsI recommend to use lodash.js : lodash.com/docs#sortBy
-
Sebastian Simon about 2 yearsThe pattern for sorting by properties is
cars.sort((a, b) =>
…)
witha.prop
andb.prop
.a.prop - b.prop
sorts numerically,a.prop.localeCompare(b.prop)
lexicographically, and(b.prop < a.prop) - (a.prop < b.prop)
generically. To sort descending instead of ascending, negate the return value (e.g.b.prop - a.prop
instead ofa.prop - b.prop
). To sort by multiple properties, chain other sorts with||
, e.g.b.someNumber - a.someNumber || a.someString.localeCompare(b.someString)
. -
Sebastian Simon about 2 yearsSorting by array values at a specific index is exactly the same problem as sorting by object properties — the syntax just looks different: e.g.
a[0] - b[0]
. And finally, if you’re looking to sort the properties of an object themselves, see Sort JavaScript object by key.
-
user56reinstatemonica8 almost 11 yearsSimple note for convenience: this (
a.someProp - b.someProp
) sorts from lowest to highest, and the reverse (b.someProp - a.someProp
) sorts from highest to lowest. Basically, if the function returns less than 0, a comes before b. -
Mark Schultheiss about 7 yearsTo be fully reversed the numbers need
return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
-
Marcs about 7 yearsYes, as now no reverse check on numbers, thank you, I should fix that. But why the double
!
this is fine too:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
-
Mark Schultheiss about 7 yearsThe
!!
forces type coercion to a native boolean type value as opposed to the "falsy" nature of the JavaScript value, not strictly needed but clarifies purpose at least to me. Note that when you return a value with!!
it is a native Boolean type as opposed to a native type with a "falsy" value which is to say thetypeof !!undefined
ortypeof !!null
etc. return "boolean" Note that!!" "
istrue
but!!""
isfalse
(space, no space in the string) but you probably knew that already. -
Cole over 5 yearsAlso note that this solution only works for when the properties you're sorting by are numbers. This works in the example for sorting by top speed, but if you want to sort by car brand, this solution won't sort strings alphabetically. Cheeso provides an answer for sorting by both numbers and strings.
-
daniel kullmann over 2 yearsAlso note that the sorting won't work when the numbers are very high or very low, i.e. when the subtraction operation underflows.
-
S.Serpooshan about 2 yearsgood but it seems that using
>
and<
operands for value comparision is enough to handle both numeric and string properties (notypeof
check). -
S.Serpooshan about 2 yearsIt seems that using
>
and<
operands for value comparision is enough to handle bothnumeric
andstring
properties! so the secondsort
sample always works. Also, we may add some condition for equal case to micro-improve code performance to avoid un-neccessary repositioning:(a, b) => (a.brand > b.brand) ? 1 : (a.brand < b.brand) ? -1 : 0