如何在javascript中完全获取带有重复键的JSON

Posted

技术标签:

【中文标题】如何在javascript中完全获取带有重复键的JSON【英文标题】:How to get the JSON with duplicate keys completely in javascript 【发布时间】:2015-08-30 19:14:10 【问题描述】:

我正在尝试从 url 获取 JSON,但在响应对象中删除了重复键。有没有办法在不删除重复键的情况下完全获取它?这是我的js代码

$('document').ready(function()
    var s = $.getJSON("new.json");
    console.log(s);
);

下面是我的new.json


"s": "wae",
"s": "asd"

但在控制台中,我得到的 json 对象如下

responseJSON: Object
s: "asd"

提前致谢

【问题讨论】:

唯一的方法是手动解析 JSON(例如,将 JSON 作为普通文本获取) 确实如此。您必须从头开始编写一个自定义 JSON 解析器(除非其他人已经发布了一个,但我并没有放弃任何示例,而且库推荐无论如何都是题外话)。对于 *** 来说,这可能过于宽泛。 【参考方案1】:

如果您无法更改服务器响应,对于简单的 JSON 数据,您可以像文本一样请求 json,然后像字符串一样解析它:

var check = new RegExp('["\']([^\'"]*)[\'"][^:]*:[^"\']*["\']([^\'"]*)[\'"]',"g");
    $.ajax(
        url : "text.json",
        dataType : "text",
        success : function(data)
            var newData = ;
            data.replace(check,function(a,b,c)
                if(typeof newData[b] == "undefined")
                    newData[b] = c;
                else if(typeof newData[b] == "object")
                    newData[b].push(c);
                else
                    var ca = newData[b];
                    newData[b] = [ca,c];                     
                
                return a;
            );
            console.log(newData);
            console.log($.parseJSON(data));
        ,
        error : function(e,a)
            console.log(e,a);
        
    );

在此代码中newData 与您的 json 是:

"s": ["wae","asd"]

【讨论】:

【参考方案2】:

JSON 对象中的键应该是唯一的。否则,具有值的最后一个键通常是请求该键时提供的键。具有相同的键也使得区分对象的属性变得更加困难。密钥的全部意义在于使其可访问和可用。

要解决这个问题,您总是可以:

    更改 JSON 中的键

    更改 JSON 以包含数组

    "s": ["wae","asd"]

The javascript Object Notation (JSON) Data Interchange Format) (RFC7159) 说:

对象中的名称应该是唯一的。

在这种情况下应该必须理解为RFC 2119中指定的

应该这个词,或形容词“推荐”,意味着可能有 在特定情况下存在忽略特定情况的正当理由 项目,但必须仔细理解其全部含义 在选择不同的课程之前称重。

RFC 7159 解释了为什么唯一键是好的: > 从某种意义上说,名称都是唯一的对象是可互操作的 > 接收该对象的所有软件实现都将同意 > 名称-值映射。当对象中的名称不是 > 独特的,接收此类对象的软件的行为是 > 不可预测。许多实现报告姓氏/值对 > 仅限。其他实现报告错误或无法解析 > 对象,一些实现报告所有的名称/值对, > 包括重复项。 > > 观察到 JSON 解析库在是否 > 或者它们是否使对象成员的顺序对调用可见 > 软件。行为不依赖于成员的实现 > 从某种意义上说,订购将是可互操作的 > 受这些差异的影响。

【讨论】:

虽然这都是很好的建议,但实际上并不能回答问题。 @Quentin 是的,但看起来他自己能够从示例中更改 JSON,而不是试图回答这个问题,我觉得尝试给出是没有害处的一个可以解决问题的良好实践的想法。上面的答案对于评论来说也相当大,并且会因缺乏格式而受到影响。 我刚刚给了一个样本。实际上我无法更改 JSON。我想知道是否可以在没有重复的情况下获取。从 cmets 我猜这是不可能的。 @Quentin ,@Craicerjack 谢谢【参考方案3】:

JSON.parse() 无法做到这一点。我相信更现代的 ES 规范声明后续键会覆盖早期键。

但是,JSON 规范不允许这样的 JSON。还有其他的解析器和序列化器可以在 JavaScript 中生成和使用这样的 JSON。例如,您可以使用 SAX 样式的 JSON 解析器clarinet:

const clarinet = require('clarinet');

const parser = clarinet.parser();
const result = [];
parser.onkey = parser.onopenobject = k => 
    result.push(key: k, value: null);
;
parser.onvalue = v => 
    result[result.length - 1].value = v;
;
parser.write('"a": "1", "a": "2"').close();

console.log(result);
// [  key: 'a', value: '1' ,  key: 'a', value: '2'  ]

如果您想知道如何在浏览器中使用require(),请了解如何使用webpack。

【讨论】:

【参考方案4】:

JSON 允许重复键,但 Javascript Objects 不允许。

因为键可以重复,这意味着 JSON 不能表示为基于键/值的字典,也不能直接转换为 Javascript Object

您必须“遍历”JSON 中的每个键/值对,然后按照您认为合适的方式对其进行处理。我不知道您要转换成什么结构,但只要它不是 Javascript Object,就可以了。例如,您可能会遍历 JSON 对象并将值输出到 .ini.css 文件,其中“键”可以重复。

JSON.parse() 将不起作用,因为它会尝试解析为不允许重复键的 Javascript Object。如果密钥被重用,解决方案是简单地覆盖任何先前的值。但是,我们可以根据 JSON.parse() 的工作方式使用代码,而不是在 Javascript Object 上设置属性,您可以从那里拆分并应用您的自定义解决方案。

您可以修改完整的 JSON 解析器,例如 json2,或使用解析器在密钥到达时流式传输,例如 clarinet 或 Oboe.js。

【讨论】:

【参考方案5】:

您可以尝试使用给定的结构多次使用相同的键:

[
  "s": "wae",
  "s": "asd"
]

正如 Craicerjack 所建议的,您还可以使用单个键为多个值使用数组:

"s": ["wae","asd"]

【讨论】:

谢谢阿文德。但我的问题是是否可以不更改 JSON。

以上是关于如何在javascript中完全获取带有重复键的JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSON 对象中获取键的值 [重复]

两个带有json键的数组[重复]

如何从 Javascript 中的对象列表中获取键的值?

如何将带有对象作为键的 Ruby 哈希对象作为 Map 对象发送到前端 Javascript

Javascript - 带有布尔键的数组?

带有var的Javascript方法[重复]