递归地单步执行 Javascript 对象

recursively stepping through a Javascript object

本文关键字:Javascript 对象 执行 单步 递归      更新时间:2023-09-26

我正在尝试学习递归地逐步浏览javascript对象。 更具体地说,我正在为函数式 JavaScript 做递归问题,这在 nodeschool.io 上很好。 我的代码没有正确递归,我不知道为什么。

这是我到目前为止的代码:

module.exports = function getDependencies (tree) {
    var arr = [];
    function findKeys(branch) {
        var branchHolder = [];
        branchHolder = branchHolder.concat(Object.keys(branch));
        //console.log(branchHolder);
        var filtered = branchHolder.filter(function (value) {
            return value !== 'name' && value !== 'version';
        })
        console.log(filtered);
        filtered.forEach(function (twig) {
            if (typeof branch[twig] === 'object' && twig === 'dependencies') {
                //console.log(twig);
                findKeys(branch[twig]);
            } else {
                //console.log(branch[twig]);
                arr.push(twig + '@' + branch[twig].version);
                //console.log(arr);
            }

            /*
            //if (branch[twig]) {console.log(branch[twig])}
            if (twig !== 'dependencies') {
                arr.push(twig + '@' + branch[twig].version)
                //console.log(arr)
            } else if (typeof branch[twig] === 'object') {
                //console.log(branch[twig]);
                findKeys(branch[twig]);
            }
            */
        })
    }
    findKeys(tree);
    return arr.sort();
}

由于某种原因,我的代码不起作用。 我测试了代码的裸骨版本,它似乎有效。

function traverse(o) {
    if (typeof o === 'object') {
        for (var key in o) {
            console.log('key: ', key);
            traverse(o[key]);
        }
    } else {
        console.log(o);
    }
}
a = {foo: 'bar', baz: 'quux', zot: [1, 2, 3, {some: 'hash'}]}
traverse(a)

有人可以告诉我这两个代码块之间有什么不同吗?

提前谢谢你。 :)

安德鲁

仔细查看递归if的结构:

if (typeof branch[twig] === 'object' && twig === 'dependencies') {
  findKeys(branch[twig]);
}

您循环访问对象的键,并且仅递归于作为对象的依赖项的键。然后,您只保存不符合此要求的内容。

现在看看数据的结构:

var loremIpsum = {
  "name": "lorem-ipsum",
  "version": "0.1.1",
  "dependencies": {
    "optimist": {
      "version": "0.3.7",
      "dependencies": {
        "wordwrap": {
          "version": "0.0.2"
        }
      }
    },
    "inflection": {
      "version": "1.2.6"
    }
  }
}

顶级对象有三个键:名称、版本和依赖项。筛选出名称和版本,并在依赖项上递归。伟大!现在,递归对象如下所示:

{
  "optimist": {
     version": "0.3.7",
    "dependencies": {
      "wordwrap": {
        "version": "0.0.2"
      }
    }
  },
  "inflection": {
    "version": "1.2.6"
  }
}

所以你保存了乐观主义者和拐点的名称和版本......但是你不要递归!因为这里的键是"乐观"和"拐点",而不是"依赖"。

这里的核心问题是,当您的递归对象具有"依赖"键时,您希望递归,但您没有足够深入地研究。似乎您对每个点上各种递归对象的确切结构感到有些困惑。

你可能想要一个看起来更像这样的递归案例:

if (typeof branch[twig] === 'object') {
  arr.push(twig + '@' + branch[twig].version);
  if (branch[twig].dependencies) {
    findKeys(branch[twig].dependencies);
  }
}

function getDependencies(tree) {
  var arr = [];
  function findKeys(branch) {
    var branches = Object.keys(branch).filter(function(value) {
      return value !== 'name' && value !== 'version';
    })
    branches.forEach(function(twig) {
      if (typeof branch[twig] === 'object') {
        arr.push(twig + '@' + branch[twig].version);
        if (branch[twig].dependencies) {
          findKeys(branch[twig].dependencies);
        }
      }
    })
  }
  findKeys(tree);
  return arr.sort();
}
var loremIpsum = {
  "name": "lorem-ipsum",
  "version": "0.1.1",
  "dependencies": {
    "optimist": {
      "version": "0.3.7",
      "dependencies": {
        "wordwrap": {
          "version": "0.0.2"
        }
      }
    },
    "inflection": {
      "version": "1.2.6"
    }
  }
}
deps = getDependencies(loremIpsum.dependencies)
document.write(JSON.stringify(deps))