最近项目里常有数据结构的转换,自己也借鉴了各路大佬的资料,学习后在这边总结一下,个人感觉实用性很强
一、数据扁平 ---->树形
数据扁平=>树形
根据某一个字段,扁平数据转树形
function dataToTree(arr, field) {
let obj = {};
根据我们指定的字段,循环传入的数组,在循环过程中,
若发现对象对应字段的值并未作为一个键存在于新建对象obj中,
那么则该值作为新建对象obj的键,arr[i]作为值且该值为数组类型,
分为一组键值对放入新建对象obj中,
(比如arr[i][field]等于0的时候,新建对象obj长这样:{0:[arr[i]]}),
否则就push进新建对象obj相同且存在的键所对应的数组中
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
if (!obj[item[field]]) {
obj[item[field]] = [item];
} else {
obj[item[field]].push(item);
}
}
let finalArr = [] as Array<any>;
//obj对象的键 其实就是我们指定的field
Object.keys(obj).forEach((key) => {
finalArr.push({
key: key,
children: obj[key],
});
});
return finalArr;
}
示例:
需要转化的扁平数据:
预期:根据字段值value,value值相同的分为一组
结果:
如上图即为我们的预期
二、数据树形---->扁平
这边提供两个方法
用reduce函数
用递归方法
树形数据如下
const dataList = [
{
id:1,
name:'小王',
children:[
{
id:12,
name:'小黑',
children:[
{
id:121,
name:'小白'
},
{
id:122,
name:'小张'
}
]
}
]
},
{
id:2,
name:'小张',
children:[
{
id:22,
name:"小刘",
children:[
{
id:221,
name:'小明',
children:[
{
id:222,
name:'小明1'
},
{
id:223,
name:'小孙'
}
]
},
{
id:224,
name:'小孙'
}
]
}
]
}
]
1、用reduce函数
在转化树形数据到扁平数据的路上,有个数组方法需要我们提前先去掌握一下数组方法 reduce
可以直接点击链接查看官方说明,懒得跳转的朋友可以直接看下文
Array.prototype.reduce() - JavaScript | MDN
Array.prototype.reduce():作用是计算数组所有元素的总和
-
语法
reduce(callbackFn, initialValue)
-
参数
-
callbackFn(prevValue,currentValue)
为数组中每个元素执行的函数。其返回值将作为下一次调用 callbackFn
时的 prevValue
参数。对于最后一次调用,返回值将作为 reduce()
的返回值。callbackFn
仅对已分配值的数组索引进行调用。不会对稀疏数组中的空槽进行调用。
该函数被调用时将传入以下参数:
prevValue
上一次调用
callbackFn
的结果。在第一次调用时,如果指定了initialValue
则为指定的值,否则为array[0]
的值。
currentValue
当前元素的值。在第一次调用时,如果指定了
initialValue
,则为array[0]
的值,否则为array[1]
。
-
initialValue
(可选)
第一次调用回调时初始化 prevValue
的值。如果指定了 initialValue
,则 callbackFn
从数组中的第一个值作为 currentValue
开始执行。如果没有指定 initialValue
,则 prevValue
初始化为数组中的第一个值,并且 callbackFn
从数组中的第二个值作为 currentValue
开始执行。在这种情况下,如果数组为空(没有第一个值可以作为 prevValue
返回),则会抛出错误。
学习了reduce以后再来看看下列转化 就会很明了
//树形转扁平
function flattenTree(data) {
return data.reduce((prev, cur) => {
prev.push({ id: cur.id, name: cur.name });
if (cur.children) {
prev.push(...flatten(cur.children));
}
return prev;
}, []);
}
const flatData = flattenTree(dataList);
console.log('flatData', flatData);
2、用递归方法
function flattenTree(tree, result = []) {
for (const node of tree) {
const { id, name, children } = node;
result.push({ id, name });
if (children && children.length > 0) {
flattenTree(children, result);
}
}
return result;
}
const flatData = flattenTree(dataList);
console.log(flatData);