递归地逐步执行Javascript对象

时间:2016-03-16 18:58:43

标签: javascript recursion

我正在尝试以递归方式逐步浏览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)

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

提前谢谢你。 :)

安德鲁

1 个答案:

答案 0 :(得分:0)

仔细查看递归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))