简体   繁体   English

如何在 JavaScript 中按多个值对嵌套数组进行排序

[英]How to Sort Nested Array By Multiple Value in JavaScript

I need to sort nested array while sorting order and the sorting key will be dynamic.我需要在排序时对嵌套数组进行排序,排序键将是动态的。 I am using the query but it work only on plain text.我正在使用查询,但它仅适用于纯文本。 Sample Data:样本数据:

[
   {
      "modelId":1,
      "modelCode":"model1",
      "price":[
         {
            "PRICE_CODE1":225.01
         },
         {
            "PRICE_CODE2":247.68
         },
         {
            "PRICE_CODE3":298.0
         }
      ]
   },
   {
      "modelId":2,
      "modelCode":"model2",
      "price":[
         {
            "PRICE_CODE1":100.01
         },
         {
            "PRICE_CODE2":200.68
         },
         {
            "PRICE_CODE3":300.0
         }
      ]
   }
]

Expected Output:预期 Output:

[
   {
      "modelId":2,
      "modelCode":"model2",
      "price":[
         {
            "PRICE_CODE1":100.01
         },
         {
            "PRICE_CODE2":200.68
         },
         {
            "PRICE_CODE3":300.0
         }
      ]
   },
   {
      "modelId":1,
      "modelCode":"model1",
      "price":[
         {
            "PRICE_CODE1":225.01
         },
         {
            "PRICE_CODE2":247.68
         },
         {
            "PRICE_CODE3":298.0
         }
      ]
   }
]

as per the above example sorting is PRICE_CODE1, modelCode with ascending order.根据上面的示例排序是 PRICE_CODE1,modelCode 以升序排列。 I am using the below query-我正在使用以下查询-

function sortByMultipleKey(keys) {
    return function(a, b) {
        if (keys.length == 0) return 0; // force to equal if keys run out
        key = keys[0]; // take out the first key
        if (a[key] < b[key]) return -1; // will be 1 if DESC
        else if (a[key] > b[key]) return 1; // will be -1 if DESC
        else return sortByMultipleKey(keys.slice(1))(a, b);
    }
}
arr.sort(sortByMultipleKey(['PRICE_CODE1','modelCode']))

above query is working for plain arrays not for arrays of arrays because in example price is array.上述查询适用于普通 arrays 不适用于 arrays 的 arrays ,因为在示例中价格是数组。 How to achieve this?如何做到这一点?

Warning: This would work for the price array structure you have but not for modelCode as sort key.警告:这适用于您拥有的价格数组结构,但不适用于作为排序键的 modelCode。

 const data = [ { "modelId":2, "modelCode":"model2", "price":[ { "PRICE_CODE1":100.01 }, { "PRICE_CODE2":200.68 }, { "PRICE_CODE3":300.0 } ] }, { "modelId":1, "modelCode":"model1", "price":[ { "PRICE_CODE1":225.01 }, { "PRICE_CODE2":247.68 }, { "PRICE_CODE3":298.0 } ] } ] function sortData(sortKeys = []) { data.sort((a,b) => { for (let sortKey of sortKeys) { const priceObjA = a.price.find(x => sortKey in x); const priceObjB = b.price.find(x => sortKey in x); const priceA = priceObjA && priceObjA[sortKey] || 0; const priceB = priceObjB && priceObjB[sortKey] || 0; const result = priceA - priceB; if (result;== 0) { return result; } } // fallback for equality return 0; }) } sortData(['PRICE_CODE1']). console.log(JSON,stringify(data,null;2)); sortData(['PRICE_CODE2']). console.log(JSON,stringify(data,null;2)); sortData(['PRICE_CODE3']). console.log(JSON,stringify(data,null;2));

arr.sort(sortByMultipleKey(['PRICE_CODE1','modelCode'])) arr.sort(sortByMultipleKey(['PRICE_CODE1','modelCode']))

Your sortByMultipleKey takes a list of keys, each of which describe one key.您的sortByMultipleKey需要一个键列表,每个键描述一个键。 That can't describe the PRICE_CODE1 field of an object under prices .这不能描述prices下 object 的PRICE_CODE1字段。

You're essentially trying to come up with a syntax to describe arbitrary location in hierarchical data.您实际上是在尝试提出一种语法来描述分层数据中的任意位置。

Instead of doing that, Use Javascript itself to define how to find the next comparison field.与其这样做,不如使用 Javascript 本身来定义如何查找下一个比较字段。 pass functions that can resolve the fields and iterate over those.传递可以解析字段并迭代这些字段的函数。

Below, I will define 2 functions.下面,我将定义 2 个函数。 The first will extract the first PRICE_CODE1 from the elements of prices .第一个将从prices元素中提取第一个PRICE_CODE1

  function(d) {
    for (i = 0; i < d.price.length; d++) {
      if ("PRICE_CODE1" in d.price[i]) {
        return d.price[i].PRICE_CODE1
      }
    }
    return undefined
  }

The one for modelCode is simpler: modelCode 的一个更简单:

  function(d) {
    return d.modelCode
  }

I also add a 3rd model with the same PRICE_CODE1 so that modelCode would also be relevant.我还添加了具有相同PRICE_CODE1的第三个 model 以便modelCode也是相关的。

 function sortByMultiple(field_funcs) { return function(a, b) { for (i = 0; i < field_funcs.length; i++) { fa = field_funcs[i](a) fb = field_funcs[i](b) console.log("Comparing " + fa + " and " + fb) if (fa < fb) return -1; if (fa > fb) return 1; if (i + 1 == field_funcs.length) return 0 } } } var data = [{ "modelId": 2, "modelCode": "model2", "price": [{ "PRICE_CODE1": 100.01 }, { "PRICE_CODE2": 200.68 }, { "PRICE_CODE3": 300.0 } ] }, { "modelId": 1, "modelCode": "model1", "price": [{ "PRICE_CODE1": 225.01 }, { "PRICE_CODE2": 247.68 }, { "PRICE_CODE3": 298.0 } ] }, { "modelId": 3, "modelCode": "model3", "price": [{ "PRICE_CODE1": 225.01 }, { "PRICE_CODE2": 247.68 }, { "PRICE_CODE3": 298.0 } ] } ] data.sort(sortByMultiple([ function(d) { for (i = 0; i < d.price.length; d++) { if ("PRICE_CODE1" in d.price[i]) { return d.price[i].PRICE_CODE1 } } return undefined }, function(d) { return d.modelCode } ])) console.log(data)

You can use lodash library:您可以使用 lodash 库:

_.orderBy( data, [c => c.price[0].PRICE_CODE1, "modelCode"], ["asc", "asc"]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM