【问题标题】:How to create a JavaScript function to lookup objects and arrays nested within each other如何创建一个 JavaScript 函数来查找相互嵌套的对象和数组
【发布时间】:2019-02-25 19:08:38
【问题描述】:

我有一个带有嵌套数组的对象和如下所示的对象:

// Recursive nested objects & arrays:
var obj = {
  children: [{
      parentname: "level 0, Benny",
      children: [{
          parentname: "level 0.0, Stevey",
          children: [{
              parentname: "level 0.0.0, Betty",
              children: []
            },
            {
              parentname: "level 0.0.1, AFGNCAAP",
              children: [{
                parentname: "level 0.0.1.0, Moonman",
                children: []
              }]
            }
          ]
        },
        {
          parentname: "level 0.1, Oreo",
          children: []
        }
      ]
    },
    {
      parentname: "level 1, Jupiter",
      children: []
    }
  ]
};

// I am able to retrieve values with various length formulas:
console.log(obj.children[0].parentname); // level 0, Benny
console.log(obj.children[0].children[0].parentname); // level 0.0, Stevey
console.log(obj.children[0].children[0].children[0].parentname); // level 0.0.0, Betty
console.log(obj.children[0].children[0].children[1].parentname); // level 0.0.1, AFGNCAAP
console.log(obj.children[0].children[0].children[1].children[0].parentname); // level 0.0.1.0, Moonman
console.log(obj.children[0].children[1].parentname); // level 0.1, Oreo
console.log(obj.children[1].parentname); // level 1, Jupiter


// And I able to reduce formulas into functions...per level of nesting, example 1 level:
function getNameWorking1(name, level) {
  console.log(obj[name][level].parentname);
}
getNameWorking1(["children"], [1]) // level 1, Jupiter

// And example 2 levels:
function getNameWorking2(name, level) {
  console.log(obj[name][level[0]][name][level[1]].parentname);
}
getNameWorking2(["children"], [
  [0],
  [1]
]) // level 0.1, Oreo

// I am trying to create a single function that I can send a parameter with the sequence of property name & array values.  This does not work:
function getNameNotWorking(parameter) {
  console.log(obj[parameter].parentname);
}
getNameNotWorking("[children][1]");
getNameNotWorking("[children][0][children][1]");

我正在尝试创建一个函数,我可以发送一个带有属性名称和数组值序列的参数。最后一个功能不起作用。有关如何执行此操作的任何帮助?

顺便说一句。我有一个适用于此的递归函数。但它每次都从头开始工作,并查看每个嵌套对象和数组,直到找到我要查找的项目。这似乎重复做可能过分了。所以我正在寻找一种方法来查找对象,一旦我已经知道它的位置 - 通过所有子数组值。

【问题讨论】:

  • “这似乎重复做可能有点过分......” - 不要过早优化
  • 你能发布你拥有的工作代码吗?我不明白您所说的“一旦我已经知道它的位置”是什么意思。
  • @adam 我的赞成票?
  • @Gaurav Saraswat,我早些时候试图投票,但它告诉我我不能......我想是因为我的排名太低了。对不起,我是新人,我刚刚创建了一个帐户。但它让我现在投票!非常感谢!
  • 哦。不用担心 。一切顺利:)

标签: javascript object recursion nested


【解决方案1】:

我觉得你应该pass your parameters separated by white sapace 而不是用方括号括起来以使解析和解决方案更容易

而且。给你:)

function getNameWorking1(parameter, obj) {
  paramsList = parameter.split(' ').filter(prop => Boolean(prop)).map(prop => prop.trim());

  return paramsList.reduce((val, prop) => {
    return val[prop];
  }, obj).parentname;
}


//Working example:

var obj = {
  children: [{
      parentname: "level 0, Benny",
      children: [{
          parentname: "level 0.0, Stevey",
          children: [{
              parentname: "level 0.0.0, Betty",
              children: []
            },
            {
              parentname: "level 0.0.1, AFGNCAAP",
              children: [{
                parentname: "level 0.0.1.0, Moonman",
                children: []
              }]
            }
          ]
        },
        {
          parentname: "level 0.1, Oreo",
          children: []
        }
      ]
    },
    {
      parentname: "level 1, Jupiter",
      children: []
    }
  ]
};

console.log(getNameWorking1("children 1", obj));
console.log(getNameWorking1("children 0 children 1", obj));

【讨论】:

  • 我对此进行了修改以稍微减少它,使其他键可重复使用,并创建了类似的设置功能。我是新手,所以我不知道分享我的修改的最佳方式,所以我将它们发布在link。让我知道你的想法。
  • 是的。我复制粘贴了你的上一个。注释中的代码,这同样是正确的
【解决方案2】:

您的函数不起作用,因为它采用完整的字符串 "[children][1]" 并将其添加到 parameter 的位置,即它正在查找未定义的 obj["[children][1]"].parentname

您需要单独输入每个键作为参数。由于无法知道需要传递多少参数,所以需要遍历全局arguments对象。

因此,您的函数将如下所示:

function getNameNotWorking() {
  var returnValue = obj;
  for (let i = 0; i < arguments.length; i++) {
    returnValue = returnValue[arguments[i]];
  }
    console.log(returnValue);
}

点击 here 获取 Codepen 示例。

【讨论】:

    【解决方案3】:

    你可以用正则表达式和reduce做这样的事情

    const obj = {children:[{parentname:"level 0, Benny",children:[{parentname:"level 0.0, Stevey",children:[{parentname:"level 0.0.0, Betty",children:[]},{parentname:"level 0.0.1, AFGNCAAP",children:[{parentname:"level 0.0.1.0, Moonman",children:[]}]}]},{parentname:"level 0.1, Oreo",children:[]}]},{parentname:"level 1, Jupiter",children:[]}]}
    
    const getNested = (object, str) => {
      let matches = [],
          match,
          regex = /\[(.*?)\]/g;
    
      while (match = regex.exec(str)) {
        matches.push(match[1]);
      }
    
      return matches.reduce((acc, key) => (acc || {})[key], object)
    }
    
    const nested = getNested(obj, "[children][0][children][1]")
    
    console.log(nested)
    • 使用/\[(.*?)\]/g获取捕获组中的键名(Regex101
    • 使用 exec 将捕获组中的所有键名获取到数组中

      // matches
      ["children", "0", "children", "1" ]
      
    • 使用reduce递归获取对象的嵌套属性

    【讨论】:

      【解决方案4】:

      查看JsonPath。它提供了一个干净的界面来选择没有对象的 JSON 属性,并且有很多 JavaScript SDKs 用于它。

      【讨论】:

      • 您会想到哪种 JavaScript 实现?最重要的是,您将如何将其应用于 OP 的具体问题?
      • npmjs.com/package/jsonpath 看起来是最常用的 JsonPath SDK(至少对于 nodejs)。将 JsonPath 与模板字符串结合起来可能有助于缓解 OP 的问题,因为 obj[parameter].parentname 可以表示为静态 JsonPath 指令。
      猜你喜欢
      • 2022-11-03
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2020-12-21
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多