【问题标题】:JS: return default value if null along nested dictionary path [duplicate]JS:如果沿嵌套字典路径为空,则返回默认值[重复]
【发布时间】:2020-12-26 17:36:24
【问题描述】:

我有一个高度嵌套的 JSON 结构,我可以像这样提取单个信息

let result = data["a"]["b"][0]["c"]["d"][0]["e"][0]

什么是提取数据的优雅方式?另外,当a,b,c,d,e中的任何一个都不存在或数组不包含元素0时,是否可以将结果分配给nullundefined

【问题讨论】:

  • 我最喜欢的解决方案是链接问题中的_try函数,用于长时间导航,直到所有目标都支持可选的链接运算符
  • @CristianTraìna 这不再是必需的,因为它现在属于 ECMA 标准,并且可以通过旧目标的转译(使用 webpack)或直接在 JS 引擎(节点和浏览器)中得到支持。跨度>
  • @zmo 我同意,但不是每个人都在使用 Babel :) 有些人仍然为浏览器编写 JavaScript。顺便说一句,链接的问题还包含对可选链接运算符的引用
  • 我不同意将问题作为重复而结束,实际上我只是添加了我的投票。虽然我认为可选链应该比_try 函数更受欢迎,因为现在主流浏览器都支持它,它在标准中,并且为了向后兼容,有 babel。

标签: javascript


【解决方案1】:

使用最新的 Javascript,您可以使用 optional chaining operator:

let result = data?.a?.b?.[0]?.c?.d?.[0]?.e?.[0]

【讨论】:

  • 这不适用于问题中的字典格式,仅适用于嵌套对象
  • hum @Shraneid 你的评论让我有点难过。在 javascript 中,没有“类字典格式”之类的东西,只有对象,属性访问可以通过两种表示法完成:foo.barfoo['bar']。你不必相信我的话,just have a look at the documentation on MDN
  • 是的,你是对的,很抱歉,来自这里的 python。但是括号符号仅适用于索引而不是键(由于某种原因我无法理解)所以 data?.a?.b?.[0]?.c 是一个有效的语法,但 data?.a?.b ?.['test']?.c 不是我困惑的根源,对此感到抱歉
  • @Shraneid 很抱歉让您失望了,但 obj.val?.[expr] 是有效的 cf MDN
  • 这不是我说的,obj.["val"]?.val2 不起作用
【解决方案2】:

我想说最简单的选择是可选的链接运算符或其他东西,但我相信正确的方法是像JSONPath

可能还有其他库(例如 jsonpath one 或 jsonpath-plus)允许您做同样的事情。

JSONPath 是 JSON 的 XPath。

JSON 示例:

{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}

这就是您如何使用 JSONPath 表达式获取商店中所有书籍的作者的方法:

$.store.book[*].author

你可以在 JavaScript 中使用它:

const o = { /*...*/ },  // the 'store' JSON object from above
res1 = jsonPath(o, "$..author").toJSONString(); // all authors JSONPath expression
res2 = jsonPath(o, "$..author", {resultType:"PATH"}).toJSONString();

【讨论】:

    【解决方案3】:

    您可以编写一个函数path,它获取要访问的属性数组和要读取的对象:

    • 该函数是柯里化的,因此您可以构建一个访问特定路径并将其与不同对象重用的函数
    • reduce 向下钻取对象,直到 undefined 或到达路径的末尾。

    const path = p => o =>
      p.reduce( (res, pp) =>
                  res === undefined ? res : res[pp]
              , o
              );
              
              
    const abcd = path(['a', 'b', 'c', 'd']);
    
    console.log(abcd({}));
    console.log(abcd({a: 1}));
    console.log(abcd({a: {b: {}}}));
    console.log(abcd({a: {b: {c: {d: 42}}}}));

    【讨论】:

      猜你喜欢
      • 2011-02-05
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      相关资源
      最近更新 更多