【问题标题】:How do I sort this JSON Object by price in Javascript? [closed]如何在 Javascript 中按价格对这个 JSON 对象进行排序? [关闭]
【发布时间】:2016-12-16 18:31:49
【问题描述】:

我有一个 JSON 对象,我想按价格从小到大排序。

{
 "BEY": {
  "1": {
    "price": 2280,
    "airline": "QR",
  },
  "2": {
    "price": 2108,
    "airline": "UA",
  }
 },
 "BKK": {
  "1": {
    "price": 2956,
    "airline": "QR",
  },
  "2": {
    "price": 1718,
    "airline": "WS",
  }
 }
}

我想重新格式化它,以便关键是机票的价格。例如:

{ 
  1718: {
   "airline" : "WS",
   "IATA_Code" : "BKK"
  },
  2108: {
   "airline" : "UA",
   "IATA_Code" : "BEY"
  },
  2280: {
   "airline" : "QR",
   "IATA_Code" : "BEY"
  },
  2956: {
   "airline" : "QR",
   "IATA_Code" : "BKK"
  }
}

【问题讨论】:

  • 对象是无序的。您必须首先将数据结构更改为数组。 (或者在迭代这个对象时做一些非常有创意的向后弯曲。)
  • 如果两张票的价格相同怎么办?顺便说一句,“JSON 对象”是 JavaScript 对象的错误名称。请阅读json标签的使用说明。
  • 评论不用于扩展讨论;这个对话是moved to chat

标签: javascript arrays json sorting


【解决方案1】:

有三个问题会阻止您完成此任务。

  1. 您将不得不爬过对象和子对象以提取所需的键值。

  2. 此外,您不能对对象中的对象进行排序。您可以改为使用数组来执行此操作。我将您的结构转换为对象数组。

  3. 在删除 "airline" 值后面的那些杂散逗号之前,您将无法正确解析 JSON。请参阅文本区域元素内的有效 JSON。

因此,在开始转换 JSON 之前,您需要使用 JSLint 或基于它构建的其他工具(JSHint 等...)并验证您的 JSON 是否正确;确实有效。

var inputJSON = JSON.parse(document.getElementById('json-data').value);
var outputJSON = JSON.stringify(convert(inputJSON), null, 4);

document.body.innerHTML = '<pre>' + outputJSON + '</pre>';

function convert(data) {
  var result = [];
  Object.keys(data).forEach(function(code) {
    Object.keys(data[code]).forEach(function(ticket) {
      var record = {
        'IATA_Code': code
      };
      Object.keys(data[code][ticket]).forEach(function(key) {
        record[key] = data[code][ticket][key];
      });
      result.push(record);
    });
  });
  return result.sort(function(a, b) {
    return a.price > b.price;
  });
};
<textarea id="json-data">
{
  "BEY": {
    "1": { "price": 2280, "airline": "QR" },
    "2": { "price": 2108, "airline": "UA" }
  },
  "BKK": {
    "1": { "price": 2956, "airline": "QR" },
    "2": { "price": 1718, "airline": "WS" }
  }
}
</textarea>

点击后的有效JSON结果:▶运行代码sn-p按钮。

[{
  "IATA_Code": "BKK",
  "price": 1718,
  "airline": "WS"
}, {
  "IATA_Code": "BEY",
  "price": 2108,
  "airline": "UA"
}, {
  "IATA_Code": "BEY",
  "price": 2280,
  "airline": "QR"
}, {
  "IATA_Code": "BKK",
  "price": 2956,
  "airline": "QR"
}]

【讨论】:

  • 您的 data 不是 JSON;它是一个 Javascript 对象。你没有回答问题,抱歉。 -1
  • @LightnessRacesinOrbit 在我的回复中,我从未使用过 JSON 一词。我知道这是一个 JavaScript 对象。所以,我不知道你指的是什么。问题是如何将数据转换成这样那样的结构,然后按价格排序。
  • “我在回复中从未使用过 JSON 一词。我知道这是一个 JavaScript 对象。所以,我不知道你指的是什么。”问题在标题、正文和标签中多次说“JSON”。有助于在回答之前阅读它:)
  • @LightnessRacesinOrbit 好的,我将 JSObject 迁移到 JSON 字符串并将其放置在文本区域中。我注意到无效的 JSON 语法(杂散逗号)。
  • 现在好多了:-)
【解决方案2】:

当您有多个具有相同价格的条目时,您需要考虑您的输出数据结构。由于您希望价格成为键,这是不可能的,除非您预见为每个键存储一个数组:然后您可以存储一个、两个或多个相同价格的条目。

为此,您可以使用此 ES6 代码。 JSON.parseJSON.stringify 方法当然是不需要的,如果你已经在 J​​avaScript 中“活”了对象:

var obj = JSON.parse(`{
 "BEY": {
  "1": {
    "price": 2280,
    "airline": "QR"
  },
  "2": {
    "price": 2108,
    "airline": "UA"
  }
 },
 "BKK": {
  "1": {
    "price": 2956,
    "airline": "QR"
  },
  "2": {
    "price": 1718,
    "airline": "WS"
  }
 }
}`);

var result = Object.keys(obj).reduce( (acc, IATA_Code) =>
    Object.keys(obj[IATA_Code]).reduce( (acc, i) => {
        let price = obj[IATA_Code][i].price;
        acc[price] = (acc[price] || []).concat({
            airline: obj[IATA_Code][i].airline, 
            IATA_Code 
        });
        return acc;
    }, acc),
{});

console.log(JSON.stringify(result, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 您的 obj 不是 JSON;它是一个 Javascript 对象。你没有回答问题,抱歉。 -1
  • 在答案中添加了 JSON 解析,尽管 OP 可能谈论的是 JavaScript 对象,而不是 JSON。 OP 的示例无论如何都不是有效的 JSON。
  • 现在好多了。 “如果你已经在 J​​avaScript 中“活”了对象,那么当然不需要 JSON.parse 和 JSON.stringify 方法” 仍然通过暗示 JSON 可以存在于 JavaScript 中来模糊 JSON 和对象之间的界限作为文字(它不能)
  • @LightnessRacesinOrbit,感谢您的评论,但我说的是对象,驻留在内存中的东西,而不是符号。当然,我同意 JSON 与 JavaScript 对象字面量不兼容,而 OP 的符号就是这种不兼容的一个例子。
  • 没有“驻留在内存中”这样的东西。 JSON 是一种文本交换格式。一旦被解析,它就不再是 JSON 了;它是您将其解析成的任何内容。在您的代码中,这是一个 JavaScript 对象。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2011-05-12
  • 2013-07-15
  • 1970-01-01
  • 2021-06-21
  • 2018-11-25
  • 1970-01-01
  • 2016-07-09
相关资源
最近更新 更多