【问题标题】:Prevent Javascript from reordering JSON防止 Javascript 重新排序 JSON
【发布时间】:2019-06-19 10:47:18
【问题描述】:

我有这两个 JSON 映射:

{
  "1000006": "Alternate Business Phone",
  "1000008": "Alternate Home Phone",
  "1000001": "Business Phone",
  "1000003": "Clinic Phone",
  "3": "Facsimile",
  "1000007": "Home Phone",
  "1000004": "Lab Phone",
  "4": "Pager",
  "1000002": "Secure Msg Phone"
}

{
  "6": "Business Email",
  "1000005": "Deliver To Email",
  "7": "Personal Email"
}

哪些是按值字母排序的键值映射。我正在使用这两个来根据另一个下拉菜单的选定项更改下拉菜单的内容。图片说明:


已选择手机


已选择电子邮件


但是,正如您在图像中看到的那样,列表项的顺序没有被保留。

我处理列表项的 Javascript 是这样的:

  var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
  var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
  function changePhoneEmailItems()
  {
    var selectedItem = document.getElementById("addNewCategory").value;
    var options;
    if('1' === selectedItem) {
        options = options_1;
    } else {
        options = options_2;
    }
    var list = document.getElementById("addNewUsageType");
    list.options.length=0;
    for(var i in options) {
        list.add(new Option(options[i], i));
    }
  }

根据this StackOverflow answer,我需要更改我正在使用的数据结构,因为根据定义,JSON 是无序的。

我尝试将 JSON 更改为 new Map:

var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
var options_1_map = new Map(options_1);
console.log(options_1_map);

但它抛出了一个错误:

TypeError: options_1 is not iterable

如何更改 JSON 对象以保留原始顺序?

注意:我的 JSON 来自 Spring 控制器,该控制器将地图“包装”在 JSON 中以发送到视图。但如果有更明智的方式将地图从控制器传输到视图,我可以修改控制器。

编辑: 为了更好地衡量,生成 JSON 的控制器代码是:

for(int i = 1; i <= 2; i++) {
    JsonObject json = new JsonObject();
    HashMap<String, String> CDCONTMETHTP = (HashMap<String, String>)model.get("CDCONTMETHTP_" + i);
    for(Entry<String, String> option : CDCONTMETHTP.entrySet()) {
        json.addProperty(option.getKey(), option.getValue());
    }
    model.put("options_" + i, json);
}

如果需要,我可以修改。

【问题讨论】:

  • options_1 的格式不正确,无法作为参数提供给 Map 的构造函数。它需要是一个数组数组。内部数组的长度必须为 2,其中内部数组的第一个元素是键,第二个元素应该是值。见MDN Map parameters docs
  • 这是因为你想迭代一个对象而不是一个数组!
  • @zero298 您能否重新格式化 JSON 以向我展示适当的格式并将其作为答案?同样,我可以控制 JSON 离开控制器的方式,但我不确定如何修改它

标签: javascript json


【解决方案1】:

您的 JSON 映射是键值对,无法保留键的顺序。您可以将您的 JSON 映射转换为 Arrays,这保留顺序。

而不是这个 JSON:

{
  "6": "Business Email",
  "1000005": "Deliver To Email",
  "7": "Personal Email"
}

发送这个 JSON:

[
  {"id": 6, "text": "Business Email"},
  {"id": 1000005, "text": "Deliver To Email"},
  {"id": 7, "text": "Personal Email"}
]

【讨论】:

  • 您的答案有效,但我不得不修改 for 循环。我将解决方案发布为下面的答案。
  • JSON 按插入时间顺序对键进行序列化和反序列化,因此如果您使用处理此问题的库,您可以极大地影响排序。也就是说,使用列表来指定顺序可能更好,稳定的字符串化更适合将对象用作复杂的哈希键
【解决方案2】:

Like someone said here;只需在数字前加上_

o/祝你有美好的一天

【讨论】:

  • 问题在于这些是传递回控制器的数据库密钥,所以我必须稍后删除那些_
【解决方案3】:

David 的回答有效,但并非没有修改遍历元素的 for 循环。我在这里发布了完整的解决方案:

var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
function changePhoneEmailItems()
{
    var selectedItem = document.getElementById("addNewCategory").value;
    var options;
    if('1' === selectedItem) {
        options = options_1;
    } else {
        options = options_2;
    }

    var list = document.getElementById("addNewUsageType");
    list.options.length=0;
    Object.keys(options).forEach(function(i) {
        list.add(new Option(options[i].value, options[i].key))          
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-02
    • 2013-03-21
    • 2013-09-11
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多