在 Javascript 中对 JSON 对象进行排序

Posted

技术标签:

【中文标题】在 Javascript 中对 JSON 对象进行排序【英文标题】:Sorting a JSON object in Javascript 【发布时间】:2011-05-12 11:35:27 【问题描述】:

我一直在寻找这样的 JSON 对象排序

"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",
   
]

按字母顺序按“COMMERCIALNAME_E”的值获取

"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",
   
]

我找不到任何可以执行此操作的代码。谁能帮帮我?

【问题讨论】:

【参考方案1】:

首先提取JSON编码的数据:

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

然后使用自定义(用户)函数进行排序:

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;
);

我假设你想按 OBJECTID 排序,但你可以将其更改为按任何排序。

【讨论】:

既然可以JSON.parse,为什么还要eval @customcommander 很可能是因为这个答案是 10 年前的,而 JSON.parse 当时没有完整的浏览器支持。随意编辑您认为过时的答案。【参考方案2】:

你可以通过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 
// ]

示例取自here, 通过 here

了解更多信息

【讨论】:

【参考方案3】:
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);

更新:不要变异

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);

【讨论】:

是的,对 json 进行排序没有“简单”的解决方案。但是有一个解决方案......你太棒了。 感谢更新,对于可测试的代码,利用函数式编程的力量我不再在我的函数中改变 args。 注意,如果属性已经是整数,a.match 会返回失败 仅供参考,您从不使用方向参数。【参考方案4】:

从字符串中提取 JSON

var data = eval(given_JSON_string);
var results = data['results'];

通过将自定义函数传递给排序方法进行排序

results.sort(customfunction);

自定义函数可以定义为

function customfunction(a, b) 

return a.attributes.COMMERCIALNAME_E < b.attributes.COMMERCIALNAME_E ? 1 : -1;

【讨论】:

既然可以JSON.parse,为什么还要eval【参考方案5】:

您可以通过将自定义比较函数作为参数提供给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;
    
);

【讨论】:

【参考方案6】:

您无法对 JSON 字符串进行排序。JSON 是用于数据传输的对象表示法 - 即字符串。您必须将其评估为对象文字(例如,使用 eval)并在重新序列化之前进行所需的任何更改。

【讨论】:

以上是关于在 Javascript 中对 JSON 对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在每个循环中对 Json 对象进行分组

如何在 android 中对 JSON 对象键进行排序/排列? [复制]

如何在 Javascript 中对对象进行切片?

如何在 discord.js 代码块中对 json 对象值进行排序?

如何在javascript中对嵌套的对象数组进行排序?

如何在颤动中对对象列表中的json字符串进行编码