Sorting objects by property values

123,260

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"}]
Share:
123,260

Related videos on Youtube

Constructor
Author by

Constructor

Updated on July 08, 2022

Comments

  • Constructor
    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ó
      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
      Chemical Programmer over 8 years
      I recommend to use lodash.js : lodash.com/docs#sortBy
    • Sebastian Simon
      Sebastian Simon about 2 years
      The pattern for sorting by properties is cars.sort((a, b) =>) with a.prop and b.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 of a.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
      Sebastian Simon about 2 years
      Sorting 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
    user56reinstatemonica8 almost 11 years
    Simple 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
    Mark Schultheiss about 7 years
    To be fully reversed the numbers need return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
  • Marcs
    Marcs about 7 years
    Yes, 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
    Mark Schultheiss about 7 years
    The !! 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 the typeof !!undefined or typeof !!null etc. return "boolean" Note that !!" " is true but !!"" is false (space, no space in the string) but you probably knew that already.
  • Cole
    Cole over 5 years
    Also 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
    daniel kullmann over 2 years
    Also 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
    S.Serpooshan about 2 years
    good but it seems that using > and < operands for value comparision is enough to handle both numeric and string properties (no typeof check).
  • S.Serpooshan
    S.Serpooshan about 2 years
    It seems that using > and < operands for value comparision is enough to handle both numeric and string properties! so the second sort 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