1707

I've got the following objects using AJAX and stored them in an array:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

How do I create a function to sort the objects by the price property in ascending or descending order using JavaScript only?

1

28 Answers 28

2210

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));
9
  • 239
    You can use string1.localeCompare(string2) for string comparison
    – bradvido
    Commented May 27, 2014 at 13:51
  • 86
    Keep in mind that localeCompare() is case insensitive. If you want case sensitive, you can use (string1 > string2) - (string1 < string2). The boolean values are coerced to integer 0 and 1 to calculate the difference.
    – Don Kirkby
    Commented May 1, 2015 at 21:58
  • 3
    Thanks for the update, @Pointy, I don't remember running into this problem, but perhaps the behaviour has changed in the last couple of years. Regardless, the localeCompare() documentation shows that you can explicitly state whether you want case sensitivity, numeric sorting, and other options.
    – Don Kirkby
    Commented Aug 28, 2017 at 16:11
  • 6
    @sg28 I think you've misunderstood the MDN explanation. It does not say that the sort function is not reliable, it says that it is not stable. I understand why this can be confusing, but that is not a claim that it is not suitable for use. In the context of sorting algorithms, the term stable has a specific meaning - that "equal" elements in the list are sorted in the same order as in the input. This is completely unrelated to the idea of code which is unstable (i.e. not yet ready for use).
    – Stobor
    Commented Jul 30, 2018 at 1:42
  • 3
    If you want to sort by a specific string values for example by city you could use: this.homes.sort((current,next)=>{ return current.city.localeCompare(next.city)}); Commented Oct 30, 2018 at 4:13
738

Here's a more flexible version, which allows you to create reusable sort functions, and sort by any field.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

const homes=[{h_id:"3",city:"Dallas",state:"TX",zip:"75201",price:"162500"},{h_id:"4",city:"Bevery Hills",state:"CA",zip:"90210",price:"319250"},{h_id:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));

7
  • Even though this is super cool, isn't it terribly inefficient. The speed would be O(n*n). Any way to use a more efficient sort algorithm, like Quick Sort while also keeping it extensible like your answer above?
    – nickb
    Commented Oct 31, 2011 at 5:47
  • 1
    One issue I have with this is that with reverse=false, it will sort numbers as 1,2,3,4... but Strings as z,y,x...
    – Abby
    Commented Apr 26, 2012 at 13:42
  • 4
    A small enhancement: var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
    – ErikE
    Commented Aug 7, 2012 at 1:18
  • 11
    While [1,-1][+!!reverse] looks cool, it's a horrible thing to do. If a user can't call your method properly, punish him, not try to somehow make sense of it, no matter what.
    – Ingo Bürk
    Commented Dec 3, 2013 at 21:28
  • 2
    Wouldn't it be better to prepare the source data, this would cause consecutive parsing when clearly the source data needs some tweaking. Commented Mar 5, 2015 at 14:14
153

To sort it you need to create a comparator function taking two arguments. Then call the sort function with that comparator function as follows:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

If you want to sort ascending switch the expressions on each side of the minus sign.

2
87

for string sorting in case some one needs it,

const dataArr = {

  "hello": [{
    "id": 114,
    "keyword": "zzzzzz",
    "region": "Sri Lanka",
    "supportGroup": "administrators",
    "category": "Category2"
  }, {
    "id": 115,
    "keyword": "aaaaa",
    "region": "Japan",
    "supportGroup": "developers",
    "category": "Category2"
  }]

};
const sortArray = dataArr['hello'];

console.log(sortArray.sort((a, b) => {
  if (a.region < b.region)
    return -1;
  if (a.region > b.region)
    return 1;
  return 0;
}));

1
  • 3
    This should be at the top, everyone keeps talking about sorting numbers, and no one talks about sorting letters or words alphabetically. Thanks
    – Emeka Orji
    Commented Jun 14, 2022 at 16:07
55

If you have an ES6 compliant browser you can use:

The difference between ascending and descending sort order is the sign of the value returned by your compare function:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

Here's a working code snippet:

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

homes.sort((a, b) => Number(a.price) - Number(b.price));
console.log("ascending", homes);

homes.sort((a, b) => Number(b.price) - Number(a.price));
console.log("descending", homes);

0
27

I recommend GitHub: Array sortBy - a best implementation of sortBy method which uses the Schwartzian transform

But for now we are going to try this approach Gist: sortBy-old.js.
Let's create a method to sort arrays being able to arrange objects by some property.

Creating the sorting function

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };
      
  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };
  
}());

Setting unsorted data

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

Using it

Arrange the array, by "date" as String

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

If you want to ignore case sensitive, set the parser callback:

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

If you want to convert the "date" field as Date type:

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

Here you can play with the code: jsbin.com/lesebi

Thanks to @Ozesh by his feedback, the issue related to properties with falsy values was fixed.

1
  • In case you are sorting through numbers and you encounter a '0' in between the array of objects, you might notice that the above code breaks.. Here is a quick fix for that : var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } followed by: return function (array, o) { .... a = _getItem.call(o, a); a = checkNaN(a); b = _getItem.call(o, b); b = checkNaN(b); return o.desc * (a < b ? -1 : +(a > b)); });
    – Ozesh
    Commented Oct 20, 2016 at 4:29
26

You want to sort it in Javascript, right? What you want is the sort() function. In this case you need to write a comparator function and pass it to sort(), so something like this:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

Your comparator takes one of each of the nested hashes inside the array and decides which one is higher by checking the "price" field.

0
22

Use lodash.sortBy, (instructions using commonjs, you can also just put the script include-tag for the cdn at the top of your html)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

Descending order

var descendingOrder = sortBy( homes, 'price' ).reverse();

Ascending order

var ascendingOrder = sortBy( homes, 'price' );
2
  • 1
    Or const sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
    – mpen
    Commented Oct 17, 2016 at 1:13
  • not sure if loadash changed recently by now its named OrderBy import { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
    – montelof
    Commented Dec 8, 2016 at 21:56
19

I'm little late for the party but below is my logic for sorting.

function getSortedData(data, prop, isAsc) {
    return data.sort((a, b) => {
        return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
    });
}
1
  • 2
    This answer is the easiest to understand. I simplified it for my use case. function objsort(obj,prop){ return obj.sort( (a, b) => a[prop].toString().localeCompare(b[prop]) ); }
    – Ken H
    Commented Sep 3, 2021 at 14:11
15

You can use string1.localeCompare(string2) for string comparison

this.myArray.sort((a,b) => { 
    return a.stringProp.localeCompare(b.stringProp);
});

Note that localCompare is case insensitive

2
  • Note that localCompare now has options that can be used if you want case sensitive (and other options). Near-universal support in up-to-date browsers. Commented Jul 10, 2021 at 21:15
  • The best solution for array of string sorting
    – Hugo Sohm
    Commented Aug 25, 2022 at 14:16
10

While I am aware that the OP wanted to sort an array of numbers, this question has been marked as the answer for similar questions regarding strings. To that fact, the above answers do not consider sorting an array of text where casing is important. Most answers take the string values and convert them to uppercase/lowercase and then sort one way or another. The requirements that I adhere to are simple:

  • Sort alphabetically A-Z
  • Uppercase values of the same word should come before lowercase values
  • Same letter (A/a, B/b) values should be grouped together

What I expect is [ A, a, B, b, C, c ] but the answers above return A, B, C, a, b, c. I actually scratched my head on this for longer than I wanted (which is why I am posting this in hopes that it will help at least one other person). While two users mention the localeCompare function in the comments for the marked answer, I didn't see that until after I stumbled upon the function while searching around. After reading the String.prototype.localeCompare() documentation I was able to come up with this:

var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]

This tells the function to sort uppercase values before lowercase values. The second parameter in the localeCompare function is to define the locale but if you leave it as undefined it automatically figures out the locale for you.

This works the same for sorting an array of objects as well:

var values = [
    { id: 6, title: "Delta" },
    { id: 2, title: "charlie" },
    { id: 3, title: "delta" },
    { id: 1, title: "Charlie" },
    { id: 8, title: "Bravo" },
    { id: 5, title: "alpha" },
    { id: 4, title: "Alpha" },
    { id: 7, title: "bravo" }
];
var sorted = values
    .sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));
8

Here is a culmination of all answers above.

Fiddle validation: http://jsfiddle.net/bobberino/4qqk3/

var sortOn = function (arr, prop, reverse, numeric) {

    // Ensure there's a property
    if (!prop || !arr) {
        return arr
    }

    // Set up sort function
    var sort_by = function (field, rev, primer) {

        // Return the required a,b function
        return function (a, b) {

            // Reset a, b to the field
            a = primer(a[field]), b = primer(b[field]);

            // Do actual sorting, reverse as needed
            return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
        }

    }

    // Distinguish between numeric and string to prevent 100's from coming before smaller
    // e.g.
    // 1
    // 20
    // 3
    // 4000
    // 50

    if (numeric) {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to a string.
            // - Replace any non numeric characters.
            // - Parse as float to allow 0.02 values.
            return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));

        }));
    } else {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to string.
            return String(a).toUpperCase();

        }));
    }


}
2
  • can you please explain what is the significance of having * (rev ? -1 : 1);
    – TechTurtle
    Commented Sep 28, 2017 at 16:59
  • That's to reverse the order (ascending vs descending) the rev portion just flips normal results when the rev argument is true. Otherwise it'll just multiple by 1 which does nothing, when set, it'll multiply the result by -1, thereby inverting the result.
    – bob
    Commented Sep 29, 2017 at 18:16
7

A more LINQ like solution:

Array.prototype.orderBy = function (selector, desc = false) {
    return [...this].sort((a, b) => {
        a = selector(a);
        b = selector(b);

        if (a == b) return 0;
        return (desc ? a > b : a < b) ? -1 : 1;
    });
}

Advantages:

  • autocompletion for properties
  • extends array prototype
  • does not change array
  • easy to use in method chaining

Usage:

Array.prototype.orderBy = function(selector, desc = false) {
  return [...this].sort((a, b) => {
    a = selector(a);
    b = selector(b);

    if (a == b) return 0;
    return (desc ? a > b : a < b) ? -1 : 1;
  });
};

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

let sorted_homes = homes.orderBy(h => parseFloat(h.price));
console.log("sorted by price", sorted_homes);

let sorted_homes_desc = homes.orderBy(h => h.city, true);
console.log("sorted by City descending", sorted_homes_desc);

0
6

You can use the JavaScript sort method with a callback function:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);
6

For sorting a array you must define a comparator function. This function always be different on your desired sorting pattern or order(i.e. ascending or descending).

Let create some functions that sort an array ascending or descending and that contains object or string or numeric values.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

Sort numbers (alphabetically and ascending):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

Sort numbers (alphabetically and descending):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

Sort numbers (numerically and ascending):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

Sort numbers (numerically and descending):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

As above use sorterPriceAsc and sorterPriceDes method with your array with desired key.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
0
5

While it is a bit of an overkill for just sorting a single array, this prototype function allows to sort Javascript arrays by any key, in ascending or descending order, including nested keys, using dot syntax.

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

Usage:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

Sorting by nested properties with dot-syntax or array-syntax:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Sorting by multiple keys:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

You can fork the repo: https://github.com/eneko/Array.sortBy

1
  • I like this answer a lot because of sortBy's concise syntax. Simple to use –even with nested fields– while maintaining great code-readability. Thank you! Commented May 31, 2020 at 16:15
4

For a normal array of elements values only:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

For an array of objects:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]
3

If you use Underscore.js, try sortBy:

// price is of an integer type
_.sortBy(homes, "price"); 

// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);}); 
3

Here is a slightly modified version of elegant implementation from the book "JavaScript: The Good Parts".

NOTE: This version of by is stable. It preserves the order of the first sort while performing the next chained sort.

I have added isAscending parameter to it. Also converted it to ES6 standards and "newer" good parts as recommended by the author.

You can sort ascending as well as descending and chain sort by multiple properties.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

2
  • could we sort {"first":"Curly","last":"Howard", "property" : {"id" : "1"}} type of array by id? Commented Aug 14, 2017 at 8:29
  • yes, the function has to be slightly modified to take in a new parameter, say, nestedName. You then call by with name="property", nestedName="id" Commented Aug 15, 2017 at 21:29
3

Create a function and sort based on the input using below code

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

 }, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

 }, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);
2

For sort on multiple array object field. Enter your field name in arrprop array like ["a","b","c"] then pass in second parameter arrsource actual source we want to sort.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}
2

You will need two function

function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

Then you can apply this to any object property:

 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

0

Hi after reading this article, I made a sortComparator for my needs, with the functionality to compare more than one json attributes, and i want to share it with you.

This solution compares only strings in ascending order, but the solution can be easy extended for each attribute to support: reverse ordering, other data types, to use locale, casting etc

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

}, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

}, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

}];

// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
    // Compare the values of the first attribute
    if (a[comp[0]] === b[comp[0]]) {
        // if EQ proceed with the next attributes
        if (comp.length > 1) {
            return sortComparator(a, b, comp.slice(1));
        } else {
            // if no more attributes then return EQ
            return 0;
        }
    } else {
        // return less or great
        return (a[comp[0]] < b[comp[0]] ? -1 : 1)
    }
}

// Sort array homes
homes.sort(function(a, b) {
    return sortComparator(a, b, ['state', 'city', 'zip']);
});

// display the array
homes.forEach(function(home) {
    console.log(home.h_id, home.city, home.state, home.zip, home.price);
});

and the result is

$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500

and another sort

homes.sort(function(a, b) {
    return sortComparator(a, b, ['city', 'zip']);
});

with result

$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500
0
 function compareValues(key, order = 'asc') {
  return function innerSort(a, b) {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      // property doesn't exist on either object
      return 0;
    }

    const varA = (typeof a[key] === 'string')
      ? a[key].toUpperCase() : a[key];
    const varB = (typeof b[key] === 'string')
      ? b[key].toUpperCase() : b[key];

    let comparison = 0;
    if (varA > varB) {
      comparison = 1;
    } else if (varA < varB) {
      comparison = -1;
    }
    return (
      (order === 'desc') ? (comparison * -1) : comparison
    );
  };
}

http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc

0

I recently wrote a universal function to manage this for you if you want to use it.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){
    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){
        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);
    });

    // Sort the array based on the type given
    switch(type){
        case 'alphabetical':
            returnedArray.sort(function(a, b){
                return (a[identifier] == b[identifier]) ? 0 : (
                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]
                ) ? 1 : -1;
            });

            break;

        default:
    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}
0

You can create a function to sort the objects in the homes array by the price property in either ascending or descending order using JavaScript's sort() method while passing an optional order parameter.

Here is how you can do it:

var homes = [
    { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" },
    { "h_id": "4", "city": "Beverly Hills", "state": "CA", "zip": "90210", "price": "319250" },
    { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" }
];

function sortHomesByPrice(homesArray, order = 'ascending') {
    return homesArray.sort((a, b) => 
        order === 'ascending' ? parseFloat(a.price) - parseFloat(b.price) : parseFloat(b.price) - parseFloat(a.price)
    );
}

console.log("Ascending Order:", sortHomesByPrice(homes, 'ascending'));
console.log("Descending Order:", sortHomesByPrice(homes, 'descending'));
-1

Your request can be promptly fulfilled by effortlessly adding your objects to a TrueSet, where each object is represented by the numeric value of its price property.

const
    repr = item => Number.parseInt(item.price),

    got = TrueSet.of(repr, ORDER.ASCENDING)
        .letAll(data)

Nothing else is required.

You can check validity of the proposed solution by:

import {TrueSet} from "@ut8pia/classifier/queue/TrueSet.js";
import {ORDER} from "@ut8pia/classifier/global.js";

const 
        data = [{
                "h_id": "3",
                "city": "Dallas",
                "state": "TX",
                "zip": "75201",
                "price": "162500"
            }, {
                "h_id": "4",
                "city": "Bevery Hills",
                "state": "CA",
                "zip": "90210",
                "price": "319250"
            }, {
                "h_id": "5",
                "city": "New York",
                "state": "NY",
                "zip": "00010",
                "price": "962500"
            }, {
                "h_id": "6",
                "city": "Dallas",
                "state": "TX",
                "zip": "75201",
                "price": "90000"
            }
        ],

        expected = [{
                "h_id": "6",
                "city": "Dallas",
                "state": "TX",
                "zip": "75201",
                "price": "90000"
            }, {
                "h_id": "3",
                "city": "Dallas",
                "state": "TX",
                "zip": "75201",
                "price": "162500"
            }, {
                "h_id": "4",
                "city": "Bevery Hills",
                "state": "CA",
                "zip": "90210",
                "price": "319250"
            }, {
                "h_id": "5",
                "city": "New York",
                "state": "NY",
                "zip": "00010",
                "price": "962500"
            }
        ];


assert.deepEqual(got.toArray(), expected)  

However, you might want to use all the item properties in the representation.

const 
    repr = item => [Number.parseInt(item.price), item.state, item.zip, item.city,  item.h_id]

The TrueSet internal tree structure - a Classifier, would allow you to both query and modify your dataset based on such properties.

To get acquainted with the concepts of TrueSet, Classifier and representation function, consider exploring the @ut8pia/classifier library.

-4

You can use the below approach if you don't want to use any sort() method

function sortObj(obj) {
  let numArr = []; //the array which just includes prices as Number
  let sortedObj = [];
  obj.map((x) => {
    numArr.push(Number(x["price"]));
  });

  while (numArr.length > 0) { 
    let minIndex = numArr.indexOf(Math.min(...numArr)); //the index of cheapest home in the obj
    numArr.splice(minIndex, 1); 
    sortedObj.push(obj.splice(minIndex, 1)); // splicing cheapest home from Homes Array to sortedObj Array.
  }

  console.log(sortedObj);
}

var homes = [
  {
    h_id: "3",
    city: "Dallas",
    state: "TX",
    zip: "75201",
    price: "162500",
  },
  {
    h_id: "4",
    city: "Bevery Hills",
    state: "CA",
    zip: "90210",
    price: "319250",
  },
  {
    h_id: "5",
    city: "New York",
    state: "NY",
    zip: "00010",
    price: "962500",
  },
];
sortObj(homes);