【问题标题】:Javascript - understanding recursive inner functionJavascript - 理解递归内部函数 [已解决]
【发布时间】:2020-12-26 02:40:05
【问题描述】:

下面的代码打印出在对象中按其值搜索的键的路径:

function findKeyPath(obj, keyAttr, keyValue) {
  let path = "";

  (function findKey (obj, keyAttr, keyValue, keyPath) {

    const prevPath = `${keyPath ? keyPath + "." : ""}`;
    if (obj[keyAttr] === keyValue) {

      path = `${prevPath}${keyAttr}`;

    } else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {

      path = prevPath.slice(0, -1); // remove last dot
    }
    if (typeof obj === "object" && !Array.isArray(obj)) {
      for (const key in obj) {

        if (Array.isArray(obj[key])) {
          for (let j = 0; j < obj[key].length; j++) {

            findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`);
          }
        }
        if (obj[key] !== null && typeof obj[key] === "object") {

          findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`);
        }
      }
    }
  }(obj, keyAttr, keyValue));

  return path;
}

console.log(
  findKeyPath({
    users: [
      { name: "sam", surname: "red", age: 12 },
      { name: "sam", surname: "red", age: 42 },
      { name: "sam", surname: "red", age: 16 }
    ]
  }, "age", 16)
);

...它打印 users[2].age

尝试取出内部函数,像这样:

function findKey(obj, keyAttr, keyValue, keyPath) {
  const prevPath = `${keyPath ? keyPath + "." : ""}`;

  if (obj[keyAttr] === keyValue) {

    return `${prevPath}${keyAttr}`;

  } else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {

    return prevPath.slice(0, -1); // remove last dot
  }
  if (typeof obj === "object" && !Array.isArray(obj)) {
    for (const key in obj) {

      if (Array.isArray(obj[key])) {
        for (let j = 0; j < obj[key].length; j++) {

          findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`);
        }
      }
      if (obj[key] !== null && typeof obj[key] === "object") {

        findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`);
      }
    }
  }
}

console.log(
  findKey({
    users: [
      { name: "sam", surname: "red", age: 12 },
      { name: "sam", surname: "red", age: 42 },
      { name: "sam", surname: "red", age: 16 }
    ]
  }, "age", 16)
);

它打印 undefined。我该如何解决?

更新,现在可以使用了

function findKey(obj, keyAttr, keyValue, keyPath) {

    const prevPath = `${keyPath ? keyPath + "." : ""}`;

    let path = "";

    if (obj[keyAttr] === keyValue) {
        return `${prevPath}${keyAttr}`;
    } else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {
        return prevPath.slice(0, -1); // remove last dot
    }

    if (typeof obj === "object" && !Array.isArray(obj)) {
        for (const key in obj) {
            if (Array.isArray(obj[key])) {
                for (let j = 0; j < obj[key].length; j++) {
                    path = path.concat(findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`));
                }
            }

            if (obj[key] !== null && typeof obj[key] === "object") {
                return path.concat(findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`));
            }
        }
    }

    return path;
}

【问题讨论】:

    标签: javascript json recursion


    【解决方案1】:

    我能想到的第二个代码 sn-p 的一个问题是,我们将 path 作为一个变量,在整个 findKey 函数调用中不断更新,它是一种“受保护变量”,@987654323 @function 可以访问和修改。在第二个代码 sn-p 中,我们没有修改变量,而是直接将其返回给调用者,这部分代码可能不会返回任何内容

    if (typeof obj === "object" && !Array.isArray(obj)) {
    for (const key in obj) {
    
      if (Array.isArray(obj[key])) {
        for (let j = 0; j < obj[key].length; j++) {
    
          findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`);
        }
      }
      if (obj[key] !== null && typeof obj[key] === "object") {
    
        findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`);
      }
    }
    

    想象一下 findKey 在这里被调用并按照您的期望返回东西,但是我们没有从这个函数返回任何东西,因此 undefined 被返回。我们可能需要为这部分代码引入一个变量并存储结果并返回它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多