问: JavaScript 如何查找对象中某个 value 并返回路径上所有的 key?
- let obj = {
- key1: 'str1',
- key2: {
- key3: 'str3'
- },
- key4: {
- key5: {
- key6: 'str6',
- key7: 'str7'
- },
- key8: 'str8'
- },
- key9: 'str9'
- };
有例如上面这样一个对象, 要求封装一个函数, 传入对象和某个 value, 返回该 value 路径上的 key. 比如: searchKeys(obj, "str3"), 得到 "key3, key2".-- 来源于 @zanetti 的一篇 「博问」 https://q.cnblogs.com/q/113766/
我本想在该「博问」下作答, 但是「博客园」提示我注册尚且不满 24 小时, 不允许我回答「博问」栏目的问题. 好吧, 我确实是 3 月 16 日晚上刚刚注册的「博客园」账号, 既然无法回答那就干脆写第一篇博客. 博客的申请在 3 月 17 日早上刚刚审核通过.
言归正传, 这题要求遍历对象, 而本质其实就是对一个多叉树进行递归.
封装函数并遍历对象
第一步是最简单的, 不必多说.
- function search(object, value) {
- for (var key in object) {
- // ...
- }
- }
必须先有结果
既然知道这里需要递归, 那么最重要一点就是必须找到结果, 因为没有最终结果的递归操作肯定会「无法自拔」. 此题, 当 key 对应的值等于 value 时, 递归就将结束, 代码如下.
- if (object[key] == value) {
- return [key];
- } else {
- }
然后思考递归
现在需要分析一下, 如果没有找到 value,object[key] 的值有哪些情况?
1, 一个不等于 value 字符串; 2, 一个对象.
如果是一个字符串, 那么肯定是不需要任何操作, 继续下一次 for ... in 循环即可. 如果是一个对象, 那么继续对这个对象重复刚刚的遍历操作, 此处即递归.
- if (typeof(object[key]) == "object") {
- var temp = search(object[key], value);
- }
继续分析 (理论上脑子里面可以假设这是倒数第二步即可).
假如递归的操作并没有找到 value, 那么返回值是什么? 我用一个 temp 变量来接收返回值, 而没有找到 value 肯定就没有返回值, 所以 temp 应该是 undefined.
假如递归的操作找到了 value, 那么返回值是什么? 对, 是 key(这里我为了输出方便, 使用了数组存放所有的 key). 既然得到了最后一步的 key, 把他与当前的 key 放在一起即可.
- if (temp == undefined) {
- } else {
- return [key, temp].flat();
- }
这里我是用了 flat() 方法, 这个方法可以抹平一个数组. 不管嵌套了多少的数组, 都会展开成为一个无嵌套数组.
举个例子: array = ["a", "b", ["c", "d"], ["e", ["f"]]] => array = array.flat() => array = ["a", "b", "c", "d", "e", "f"];
最终函数
- function search(object, value) {
- for (var key in object) {
- if (object[key] == value) {
- return [key];
- } else if (typeof(object[key]) == "object") {
- var temp = search(object[key], value);
- if (temp == undefined) {
- } else {
- return [key, temp].flat();
- }
- } else {
- }
- }
- }
再稍微修改一下.
- function search(object, value) {
- for (var key in object) {
- if (object[key] == value) return [key];
- if (typeof(object[key]) == "object") {
- var temp = search(object[key], value);
- if (temp) return [key, temp].flat();
- }
- }
- }
至此, 第一篇博客写完. 我接触 JavaScript 的时间不长, 也是个新手, 好在这题主要是递归算法, 如有错误请在评论中指出, 不胜感激!
来源: http://www.bubuko.com/infodetail-2990224.html