赞
踩
- MockData = {
- id: 1,
- name: "xiaoming",
- children: [
- {
- id: 2,
- name: "xiaohonng2",
- children: [{ id: 5, name: " xiao5", children: [] }],
- },
- { id: 3, name: " xiao3", children: [] },
- { id: 4, name: " xiao4", children: [] },
- ],
- };
-
- function tarverse(nodes, id) {
- let result;
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].id == id) {
- result = nodes[i];
- return result;
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- result = tarverse(nodes[i].children, id);
- }
- if (result) return result;
- }
- return result;
- }
-
- let node = tarverse(MockData, 3);
- console.log(node, "node");
- MockData = {
- id: 1,
- name: "xiaoming",
- children: [
- {
- id: 2,
- name: "xiaohonng2",
- children: [{ id: 5, name: " xiao5", children: [] }],
- },
- { id: 3, name: " xiao3", children: [] },
- { id: 4, name: " xiao4", children: [] },
- ],
- };
-
- function tarverse(nodes, id) {
- let result = null;
- console.log(nodes)
- if (nodes.id == id) {
- result = nodes
- return result
- }
- if (nodes.children && nodes.children.length > 0) {
- for (let i = 0; i < nodes.children.length; i++) {
- result = tarverse(nodes.children[i], id)
- if (result) return result
- }
- }
- return result
- }
-
- let node = tarverse(MockData, 3);
- console.log(node, "node");
- const traverse = (data, fn, childName = "children") => {
- if(fn(data)== false) {
- return false
- }
- if (data && data[childName]) {
- for(let i = 0; i < data[childName].length; i++) {
- if(!traverse(data[childName][i], fn, childName)) return false
- }
- }
- return true;
- };
---------------------------------- 以上是新版,下面的就不要看了 ---------------------------------------------
业务中,遍历一个东西,经常是,拿到一个对象,遍历他的一个 数组属性。
因为,遍历几乎都是针对数组的,只有数组,才会存放很多东西,需要遍历。
- const traverse = (data, fn, childName = "children") => {
- fn(data);
- if (data && data[childName].length > 0) {
- for(let i = 0; i < data[childName].length; i++) {
- traverse(data[childName][i], fn, childName);
- }
- }
- };
递归:
- // dataTree 是 对象 childre 是数组
- // *这个方法递归的现象是: 把第一个元素递归出来,然后再第一个元素的第一个子元素再递归出来,总之,看下面
- // 1 1.1 1.1.1 1.1的子节点递归完了,就 1.1 1.1.2 1.1.2.1 。 即先把第一个尾部子节点,先递归出来。?
- function bianli_digui(dataTree,childrenName = "children") {
-
-
-
-
- for (let i = 0; i < dataTree.length; i++) {
-
- if (dataTree[childrenName]&&dataTree[childrenName].length>0){
- bianli_digui(dataTree[childrenName],childrenName)
-
- }
- }
- }
-
- 待测试
方法二: 递归遍历,且可以传入Fn,不用,去改变里面的数组
- var traverse = function traverse(data, fn, childrenName = "children") {
- if (fn(data) === false) {
- return false;
- }
-
- if (data && data[childrenName]) {
- for (var i = 0 ; i <= data[childrenName].length - 1; i++) {
- if (!traverse(data[childrenName][i], fn, childrenName)) return false;
- }
- }
- return true;
- };
注意了: 这里很重点,也是我想了很久才想到的。
tip:1. 之前发现这个是全递归,怎么中途找到想到的数据就结束呢?
2. 里面的return false 和 return true 有什么用,你会发现,你把全部return false删除掉也能 正常使用这个函数。
总结: 如果要找到数据,就推出整个递归循环,那么就要,你的Fn函数,最后返回 false就行了。
为什么: 1. fn(data)返回false,就进入了 if(fn(data)===false){ return false } 里面。
然后推出当前的递归,。
2. 退出当前递归后,来到 if(!traverse(xxxx))这里,如果为真,又return false,那么又退出当前递归。 然后如此循环,就会推出整个递归。
这里是工作中实际应用, 拿新的tree的数据, 用两个递归把 这个旧的tree 改成 新的tree
-
- //* 拷贝并递归修改文件树数据,用res.Tree的结构 用DirectoryTree的数据
- let My_DirectoryTree = _.cloneDeep(DirectoryTreeDatas)
- CMFunc.traverseTree(res.Data, (resTree) => {
- CMFunc.traverseTree(My_DirectoryTree, (myTree) => {
- if (myTree.id === resTree.id) {
- for (let key of Object.keys(myTree)) {
- if (key == "content") {
- resTree[key] = myTree[key]
- }
- }
- }
- })
- })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。