问: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 的一篇 「博问」

  我本想在该「博问」下作答,但是「博客园」提示我注册尚且不满 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 的时间不长,也是个新手,好在这题主要是递归算法,如有错误请在评论中指出,不胜感激!

JavaScript 遍历对象查找指定的值并返回路径的更多相关文章

  1. javaScript遍历对象、数组总结(转载)

    javaScript遍历对象.数组总结  转载来源 https://www.cnblogs.com/chenyablog/p/6477866.html 在日常工作过程中,我们对于javaScript遍 ...

  2. JS遍历对象的属性和值

    对于需要动态获取对象的某些属性和对应的值的时候,就需要遍历对象的属性和值. const user = { name: '张三', age: 20, addr: '湖北武汉', sex: '男' } / ...

  3. JavaScript 遍历对象、数组总结

    在日常工作过程中,我们对于javaScript遍历对象.数组的操作是十分的频繁的,今天抽空把经常用到的方法小结一下,方便今后参考使用!   javaScript遍历对象总结     1.使用Objec ...

  4. JavaScript遍历对象-总结一

    原生JavaScript 遍历 1.for 循环遍历 let array1 = ['a','b','c']; for (let i = 0;i < array1.length;i++){ con ...

  5. javascript遍历对象的属性

    不同类型的循环 JavaScript 支持不同类型的循环: for - 多次遍历代码块 for/in - 遍历对象属性 while - 当指定条件为 true 时循环一段代码块 do/while - ...

  6. javaScript遍历对象、数组总结

        javaScript遍历对象总结 1.使用Object.keys()遍历 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性). var obj = {'0':'a ...

  7. 关于javascript遍历对象

    1:遍历对象属性var obj={a:'aa',b:'bb'} for(var i in obj) { alert(i); //输出 a b } var obj={'a':'aa','b':'bb'} ...

  8. js中遍历对象的属性和值的方法

    鉴于循环目标是个对象,length是为undefined,用map等对数组的循环方法不行,对象就用此下方法 for(var key in _this.lists.medicines){ medicin ...

  9. JavaScript遍历对象4种方法和遍历数组的3种方式 代码

    //遍历对象 4种方法 //Object.keys(obj).forEach() console.log("keys...遍历</br>") var obj1 = { ...

随机推荐

  1. 关于Sumlime和其插件的安装

    因为近期就要去实习了,第一次实习,估计又要重新在公司的电脑里面安装Sublime和其插件了,于是现将本地的插件截图看看,顺便写一个教程吧哈哈. 我好像又省了一件事情哈哈,昨天因为懒没有尝试重新弄一次s ...

  2. Ubuntu下nagios安装(来源官网)

    Ubuntu下nagios安装(来源官网) https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/toc.html h ...

  3. Linux Shell命令系列(5) VI编辑器

    vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...

  4. MapReduce实战:邮箱统计及多输出格式实现

    紧接着上一篇博文我们学习了MapReduce得到输出格式之后,在这篇博文里,我们将通过一个实战小项目来熟悉一下MultipleOutputs(多输出)格式的用法. 项目需求: 假如这里有一份邮箱数据文 ...

  5. Oracle的表创建和事务管理

    Oracle的表创建和事务管理 - CURD,根据查询结果创建新表 - 事务管理 - 什么是事务 ,为什么要用事务 - SQL99事务隔离级别 - Oracle事务隔离级别 - 事务回滚 - 隐式回滚 ...

  6. .net中Response.End() 和Response.Redirect("http://dotnet.aspx.cc");

    问:什么情况下需要Response.End()语句,加这句有什么好处 答: 首先你要理解Response.End()的意思,它的意思是终止执行下面的语句!但有时不加和加上都一样,但还要加上好,为什么呢 ...

  7. php允许被跨域ajax请求

    只要在被请求端,加一句: header('Access-Control-Allow-Origin: *');

  8. 转---JS 获取鼠标左右键

    原文:http://blog.csdn.net/mine3333/article/details/7291557 function test() { alert(event.x+" &quo ...

  9. Centos6.8 Mysql5.6 安装配置教程

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS ...

  10. codevs 原创抄袭题 5969 [AK]刻录光盘

    题目描述 Description • 在FJOI2010夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习.组委会觉得这个主意不错!可是组委会一时 ...