Sorting a JSON object in Javascript

94,672

Solution 1

function sortJsonArrayByProperty(objArray, prop, direction){
    if (arguments.length<2) throw new Error("sortJsonArrayByProp requires 2 arguments");
    var direct = arguments.length>2 ? arguments[2] : 1; //Default to ascending

    if (objArray && objArray.constructor===Array){
        var propPath = (prop.constructor===Array) ? prop : prop.split(".");
        objArray.sort(function(a,b){
            for (var p in propPath){
                if (a[propPath[p]] && b[propPath[p]]){
                    a = a[propPath[p]];
                    b = b[propPath[p]];
                }
            }
            // convert numeric strings to integers
            a = a.match(/^\d+$/) ? +a : a;
            b = b.match(/^\d+$/) ? +b : b;
            return ( (a < b) ? -1*direct : ((a > b) ? 1*direct : 0) );
        });
    }
}

sortJsonArrayByProperty(results, 'attributes.OBJECTID');
sortJsonArrayByProperty(results, 'attributes.OBJECTID', -1);

UPDATED: DON'T MUTATE

function sortByProperty(objArray, prop, direction){
    if (arguments.length<2) throw new Error("ARRAY, AND OBJECT PROPERTY MINIMUM ARGUMENTS, OPTIONAL DIRECTION");
    if (!Array.isArray(objArray)) throw new Error("FIRST ARGUMENT NOT AN ARRAY");
    const clone = objArray.slice(0);
    const direct = arguments.length>2 ? arguments[2] : 1; //Default to ascending
    const propPath = (prop.constructor===Array) ? prop : prop.split(".");
    clone.sort(function(a,b){
        for (let p in propPath){
                if (a[propPath[p]] && b[propPath[p]]){
                    a = a[propPath[p]];
                    b = b[propPath[p]];
                }
        }
        // convert numeric strings to integers
        a = a.match(/^\d+$/) ? +a : a;
        b = b.match(/^\d+$/) ? +b : b;
        return ( (a < b) ? -1*direct : ((a > b) ? 1*direct : 0) );
    });
    return clone;
}

const resultsByObjectId = sortByProperty(results, 'attributes.OBJECTID');
const resultsByObjectIdDescending = sortByProperty(results, 'attributes.OBJECTID', -1);

Solution 2

First extract the JSON encoded data:

var data = JSON.parse(yourJSONString);
var results = data['results'];

Then sort with a custom(user) function:

results.sort(function(a,b){
    //return a.attributes.OBJECTID - b.attributes.OBJECTID;
    if(a.attributes.OBJECTID == b.attributes.OBJECTID)
        return 0;
    if(a.attributes.OBJECTID < b.attributes.OBJECTID)
        return -1;
    if(a.attributes.OBJECTID > b.attributes.OBJECTID)
        return 1;
});

I assumed you wanted to sort by OBJECTID, but you can change it to sort by anything.

Solution 3

you can sort an ordered array of anything by providing a custom compare function as a parameter to Array.Sort().

var myObject = /* json object from string */ ;

myObject.results.sort(function (a, b) {

    // a and b will be two instances of your object from your list

    // possible return values
    var a1st = -1; // negative value means left item should appear first
    var b1st =  1; // positive value means right item should appear first
    var equal = 0; // zero means objects are equal

    // compare your object's property values and determine their order
    if (b.attributes.COMMERCIALNAME_E < a.attributes.COMMERCIALNAME_E) {
        return b1st;
    }
    else if (a.attributes.COMMERCIALNAME_E < b.attributes.COMMERCIALNAME_E) {
        return a1st;
    }
    else {
        return equal;
    }
});

Solution 4

you can easily do it with array.sort()

[
    { name: "Robin Van Persie", age: 28 },
    { name: "Theo Walcott", age: 22 },
    { name: "Bacary Sagna", age: 26  }
].sort(function(obj1, obj2) {
    // Ascending: first age less than the previous
    return obj1.age - obj2.age;
});
// Returns:  
// [
//    { name: "Theo Walcott", age: 22 },
//    { name: "Bacary Sagna", age: 26  },
//    { name: "Robin Van Persie", age: 28 }
// ]

example is taken from here, learn more about it from here

Solution 5

You cannot sort a JSON string.. JSON is an Object Notation for data transport - ie, a string. You will have to evaluate it as an object literal (e.g. with eval) and make any changes you want before reserializing it.

Share:
94,672
Venkatesh Goud
Author by

Venkatesh Goud

Updated on July 13, 2022

Comments

  • Venkatesh Goud
    Venkatesh Goud almost 2 years

    I've been looking for a while to sort a JSON object like this

    {"results": [
      {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "35",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "SADD MAARAB PHARMACY",
          },
        "geometryType": "esriGeometryPoint",
       },
      {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "1",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "GAYATHY HOSPITAL  PHARMACY",
    
        },
        "geometryType": "esriGeometryPoint",
      },
         {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "255",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "AL DEWAN PHARMACY",
          },
        "geometryType": "esriGeometryPoint",
       }
    ]}
    

    alphabetically by value of "COMMERCIALNAME_E" to get

    {"results": [
       {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "255",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "AL DEWAN PHARMACY",
          },
        "geometryType": "esriGeometryPoint",
       },
      {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "1",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "GAYATHY HOSPITAL  PHARMACY",
           },
        "geometryType": "esriGeometryPoint",
       },
       {
        "layerId": 5,
        "layerName": "Pharmaceutical Entities",
        "attributes": {
          "OBJECTID": "35",
          "FACILITYTYPE": "Pharmacy",
          "FACILITYSUBTYPE": "24 Hr Pharmacy",
          "COMMERCIALNAME_E": "SADD MAARAB PHARMACY",
          },
        "geometryType": "esriGeometryPoint",
       }
    ]}
    

    I can't find any code that will do this. Can anyone give me some help?

  • Daniel Apps
    Daniel Apps over 8 years
    Yes, there is no "easy" solution for sorting json. But ther IS a solution... You are so goood.
  • PDA
    PDA almost 7 years
    thanks updated, for testable code, harness power of functional programming I no longer mutate args in my functions.
  • customcommander
    customcommander over 3 years
    Why eval when you can JSON.parse?
  • customcommander
    customcommander over 3 years
    Why eval when you can JSON.parse?
  • Alin Purcaru
    Alin Purcaru over 3 years
    @customcommander Most probably because this answer is from 10 years ago and JSON.parse did not have full browser support back then. Feel free to edit answers that you think are outdated.
  • user2051552
    user2051552 about 3 years
    Of note, a.match returns a failure if the property is already an integer
  • Chizl
    Chizl about 3 years
    FYI, you never use direction parameter.