【问题标题】:Accessing an array inside of JSON object from reviver从 reviver 访问 JSON 对象内部的数组
【发布时间】:2017-02-05 20:05:22
【问题描述】:

我有一个JSON 对象,格式类似于{"Foo": ["B","A","R"]}

我正在尝试像这样访问数组的值:

var json = '{"Foo": ["B","A","R"]}';

expression = JSON.Parse(json, function(key, value){
          if(key == "Foo"){
             console.log(value.length); // logs "3"
             console.log(value[1]);     // logs "undefined"
           } 
       });

如果我询问值的长度,它会返回数组的正确长度,但如果我询问值,它会返回 undefined,我不太清楚为什么。JSON 中还有其他值我可以正常访问,但它们不是数组。任何见解将不胜感激。谢谢!

【问题讨论】:

  • 这是您的实际代码吗? value !== Valid
  • JSON 结构存在问题 var json = '{"Foo": ["B","A","R"]}';双引号和单引号冲突
  • 这不是我的实际代码,实际代码适用于其余 JSON 值,但不适用于数组。
  • var json = '{"Foo": ["B","A","R"]}'; console.log(JSON.parse(json).Foo);
  • 您的目标仅仅是访问数组中的值,还是出于某些特定原因使用JSON.parse 的第二个可选“reviver”参数,例如想要过滤或转换对象在解析的时候?

标签: javascript arrays json node.js


【解决方案1】:

你应该像这样使用JSON.parse

var json = '{"Foo":["B","A","R"]}';
var object = JSON.parse(json);
// object is now and object containing the data from 'json'

var expression = object["Foo"][1]; // object["Foo"] refers to the
                                   // value with key "Foo"

(使用回调参数调用JSON.parse 是一种高级功能,用于转换JSON 对象,而不是读取它。不过,在几乎所有情况下,您都希望像上面的代码一样使用它,而不需要回调。)

【讨论】:

  • 我正在尝试将其解析为一个对象,以便我可以获取它们并根据 JSON 所持有的内容构建另一个对象,这是有道理的。但是,我将在没有回调的情况下尝试它。谢谢!
  • 这并没有回答为什么原始代码不起作用的问题。
  • @torazaburo 确实没有,但 IMO 的问题是无论如何都不应该使用回调来简单地读取 JSON 对象。答案不一定是关于回答字面问题,而是关于解决问题,我认为我的回答试图做到这一点。
  • 同意,但这也是一个合理的假设,即这是一个最小的例子,表明他在将 reviver 用于某些有效用例时遇到了问题。唯一知道的方法就是问他。
  • 我不知道我是否会说使用第二个参数是不好的做法,如果你可以打赌 Crockford 不会包含它。也许数据结构与他的用法不一致。第二个参数确实是在读取 JSON 时使用的。
【解决方案2】:

使用此代码

   var json = {'foo' : ['B', 'A', 'R']};
   $.each(json, function(key, value){if(key == 'foo'){console.log(value[1]);}});

你已经有一个 json 对象,所以不需要再次解析它。

【讨论】:

  • 我实际上是从文件中读取它,这就是为什么我必须解析它。
  • 什么是$.each?什么是“JSON 对象”?既然json是一个字符串,他为什么不用解析呢?
  • lol jQuery in 2016.. 只需使用内置的 Object.keys / Object.entries 和 .forEach 或 .map。
【解决方案3】:

正如另一个答案中提到的,如果您只是想检索Foo 的第二个元素,您可以在使用obj.Foo[1] 等标准属性访问技术进行解析后轻松完成。

假设您确实想使用可选的第二个“reviver”参数到JSON.parse,您需要从“reviver”回调中返回值

expression = JSON.Parse(json, function(key, value){
  if (key == "Foo"){
     console.log(value[1]);
  } 
  return value;
  ^^^^^^^^^^^^^
});

【讨论】:

    【解决方案4】:

    您无法访问 value[1] 但可以访问 value.length 的原因是(如 user663031 所述)您没有返回值。

    reviver 函数将一个值替换为另一个值,如果没有指定返回值,所有函数都将返回 undefined。 reviver 接收值的顺序是:首先是数组中的每个值,然后是数组。

    在您的代码中,每个值都已替换为“未定义”,因此该数组具有三个未定义的值,由长度报告。 value[1] 确实返回位置 1 的值,但它设置为“未定义”。

    【讨论】:

      【解决方案5】:

      当 json 字符串有数组时,reviver 函数以 index, [Object] 作为 key, value 参数调用。

      这段在解析阶段过滤对象属性的代码会很有帮助:

          var json = '{"_embedded": [{"a":"A","b":"B","links": {"c":"C"}},{"a":"A2", "b":"B2","links": {"c":"C2"}}]}';
          var schemaNames=["_embedded", "a"];
      
          var result= JSON.parse(json, function(k, v) {
            console.log(k,v);
            if ("" === k){
              return v;
            }
            // On arrays k is a number
            else if (schemaNames.indexOf(k) > -1  || !isNaN(k)){
                return v;
            }
          });
      
          console.log(JSON.stringify(result));
      

      输出:{"_embedded":[{"a":"A"},{"a":"A2"}]}

      https://jsfiddle.net/pdorgambide/vphbmtk1/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-20
        • 2020-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多