前言
这是一道工作中常用到的算法题~
你能学到
扁平数组 -> JSON 树
需求
你可能会得到类似这样的一个扁平数组,数组中的每一项都是一个对象,对象中有相关的逻辑结构的属性值~
let flatArr = [ { id: 1, title: "title1", parent_id: 0 }, { id: 2, title: "title2", parent_id: 0 }, { id: 3, title: "title2-1", parent_id: 2 }, { id: 4, title: "title3-1", parent_id: 3 }, { id: 5, title: "title4-1", parent_id: 4 }, { id: 6, title: "title3-2", parent_id: 3 },];
效果
你需要的是根据其中的逻辑,获得一个 合理 的JSON树,其中的串联关系就要根据逻辑建立~主要看那个parent_id
实现
结果数组
JSON 树形式,其实也是数组~
const result = [];
数组->map
先把数组转为 map
,id
作为 key
,本身作为 value
, 后面遍历匹配时就要靠这个 map
里的 id
const map = arr.reduce((pre, cur) => { // key 就是 id,即 cur.id; value 为值本身 pre[cur.id] = cur; return pre;}, {}); // 传入初始值为 空对象{}
这里的 arr 是外面一层函数传入的参数,等下还要封装的
ok,我们现在就拿到了扁平数组的 map 形式
vscode 中查看代码运行
关于这个在 vscode 中查看代码运行的插件可以看这篇文章:vscode插件—— Quokka.js的简单使用
遍历 数组
使用 for of
遍历数组。
父元素id
为 0 的,那么就可以直接 push
到第一层,不需要其他的处理
其余的就要找到对应的父元素,并push
到父元素之下
for (let item of arr) { // 先找到父元素为 0 的,那么就可以直接 push 到第一层,不需要其他的处理 if (item.parent_id === 0) { result.push(item); continue; } // 对于不是第一层的,我们就要先找到其父元素 if (item.parent_id in map) { const parent = map[item.parent_id]; (parent.children || (parent.children = [])).push(item); //这个简洁的方法 } }
简洁初始化并操作
这个方法是我看源码的时候学的~
从mitt、tiny-emitter源码中学习手写订阅发布
全貌
ok,封装到函数中,并返回结果即可
const flatArrToJSONTree = arr => { const result = []; const map = arr.reduce((pre, cur) => { pre[cur.id] = cur; return pre; }, {}); for (let item of arr) { if (item.parent_id === 0) { result.push(item); continue; } if (item.parent_id in map) { const parent = map[item.parent_id]; (parent.children || (parent.children = [])).push(item); } } return result;};
测试
插件数组中对象无法展开,所以赋值到控制台看看
const res = flatArrToJSONTree(flatArr);console.log(res)
JSON 树 -> 扁平数组
需求
ok,除了上面的需求,有时我们可能也需要将 一个 JSON树形式的数组扁平化
效果
const res2 = JSONTreeToFlatArr(res);
实现
相比 数组转换为 JSON 树,JSON树转化为数组的代码量就少了很多,这里就不分段细说了
const JSONTreeToFlatArr = tree => { return tree.reduce((pre, cur) => { //解构拿出属性,并给 children 一个默认值 const { children = [], ...rest } = cur; // concat 将每次结果都进行拼接 return pre.concat([{ ...rest }], JSONTreeToFlatArr(children)); //递归处理 children }, []);};
也是利用 reduce 这个方法,发现这个方法真是好用啊~concat 拼接数组,再在里面递归处理~
测试
const res2 = JSONTreeToFlatArr(res);console.log(res2);
大功告成~
学习资源
vscode插件—— Quokka.js的简单使用
从mitt、tiny-emitter源码中学习手写订阅发布
总结
文中措辞、知识点、格式如有疑问或建议,欢迎评论~你对我很重要~ ?如果有所帮助,欢迎点赞关注,一起进步⛵这对我很重要~
原文:https://juejin.cn/post/7101861338082705438