Tree Recursion:如何获取所选树节点的父根

时间:2015-01-26 23:55:03

标签: javascript json recursion dictionary tree

我有一个json对象的树状结构

{
  "saxena": {
    "chewning": {
      "betten": {},
      "ching": {},
      "kelley": {}
    },
    "kobrinsky": {
      "karniely": {},
      "naveh": {},
      "rozenfeld": {},
      "shalom": {}
    },
    "schriever": {
      "brinker": {},
      "mcleland": {},
      "merrick": {}
    },
    "vacant": {
      "akers": {},
      "carlton": {
        "marvin": {}
      },
      "fox": {
        "glover": {
          "clements": {},
          "koya": {}
        },
        "holden": {}
      }
    }
  },
  "bill": {
    "phil": {
      "bob": {},
      "smith": {},
      "hello": {}
    },
    "bye": {
      "ok": {},
      "hmm": {},
      "no": {},
      "alright": {}
    }
  }
}

根名称是saxena和bill。我想创建一个函数,可以确定用户搜索的用户的根名称。

对于最简单的情况,如果他们搜索saxena,它会返回saxena。如果他们退回账单,则返还账单。

对于更复杂的情况,如果用户搜索她下面的任何名字,将返回saxena。

例如,如果我搜索betten,akers,glovers或koya,saxena将被退回。

如果我搜索bob,smith或者好的话,账单将被退回。

到目前为止,这是我的工作。我尝试使用递归,但出于某种原因,当我找到所选名称时,我返回一个未定义的。

var findRootName = function(data, ltmName) {
    for (var key in data) {
        if (key == ltmName) {
            return key;
        } else {
            findNode(data[key], ltmName);
        }
    }
}

var findNode = function(data, ltmName) {
    for (var key in data) {
        if (key == ltmName) {
            return key;
        } else {
            findNode(data[key], ltmName);
        }
    }
}

http://jsfiddle.net/gthnfta7/7/

有人可以帮助我,弄清楚为什么我的递归函数不起作用吗?

2 个答案:

答案 0 :(得分:2)

另一种技术,如果你需要对同一数据进行多次调用,则如下所示:

function makeSearcher(data) {
    var paths = (function makePaths(data, parentPath, store) {
        var path = parentPath || [];
        results = store || {};
        Object.keys(data).forEach(function(key) {
            var newPaths = path.concat(key);
            results[key] = newPaths;
            makePaths(data[key], newPaths, results);
        });
        return results;
    })(data);
    return function(key) {
        var path = paths[key];
        return path && path[0];
    };
}

var search = makeSearcher(data);

search('clements'); //=> 'savena'

请注意,内部makePaths函数比此处的使用范围更广,因为它也可用于返回结果,如

[ "saxena", "vacant", "fox", "glover", "clements" ]

答案 1 :(得分:1)

问题是,如果找到节点,您不会返回任何内容。您可以通过这样编写来简化您的功能:

var findParent = function(data, childName) {
  for (var key in data) {
      if (key === childName || findParent(data[key], childName)) {
        return key;
      }
  }
};