一、扁平数据
const data = {
parent:[
{
name: "文件1",
pid: 1,
id: 10001
},
{
name: "文件2",
pid: 1,
id: 10002
},
{
name: "文件2-1",
pid: 2,
id: 10003
},
{
name: "文件2-2",
pid: 2,
id: 10004
},
{
name: "文件1-1-1",
pid: 4,
id: 10005
},
{
name: "文件2-1-1",
pid: 5,
id: 10006
}
],
child:[
{
name: "文件夹1",
pid: 0,
id: 1
},
{
name: "文件夹2",
pid: 0,
id: 2
},
{
name: "文件夹3",
pid: 0,
id: 3
},
{
name: "文件夹1-1",
pid: 1,
id: 4
},
{
name: "文件夹2-1",
pid: 2,
id: 5
}
]
}
二、转为多维数组
//1. 将所有的数据混合在一起
let allData = [...data.parent, ...data.child];
//2. 生成一个映射表(将id抽取出来,以对象的键值对形式展示)
//{1:{name: "文件夹1", pid: 0, id: 1}}
let treeMapList = allData.reduce((obj,cur)=>{
obj[cur["id"]] = cur;
return obj;
},{});
//3. 生成一个新的数组,根据pid在映射表中寻找并判断,相应的生成多层数组
let result = allData.reduce((arr,cur)=>{
let pid = cur.pid;
let parent = treeMapList[pid];
if(parent){
parent.children ? parent.children.push(cur) : parent.children = [cur];
}else if(pid === 0){ //这是根文件夹
arr.push(cur);
}
return arr;
},[]);
console.log(result);
关于reduce()方法
-
语法
arr.reduce(callback,[initialValue]); // reduce 为数组中的每个元素依次执行回调函数 // callback: 有四个参数 (previousValue, currentValue, index, array) // 1.1 previousValue: 上一次调用回调返回的值,或者是初始值 // 1.2 currentValue: 数组中当前被处理的元素 // 1.3 index: 当前元素在数组中的索引 // 1.4 array: 调用 reduce 的数组,这里是arr // initialValue: 作为第一次调用 callback 的第一个参数(初始值) -
关于 initialValue 参数
2.1 例子1:不设置 initialValue 参数情况
var arr = [1,2,3,4];
var sum = arr.reduce(function(prev, cur, index, arr){
console.log(prev, cur, index);
return prev + cur;
})
console.log(arr, sum);
打印结果
1 2 1
3 3 2
6 4 3
[1,2,3,4] 10
以上例子中没有设置 初始值,index 是从 1 开始的, 第一次的 prev 值是数组的第一个值,数组长度是4,但是 reduce 函数只循环了 3 次。
2.2 例子2 设置了 initialValue 参数
var arr = [1,2,3,4];
var sum = arr.reduce(function(prev, cur, index, arr){
console.log(prev, cur, index);
return prev + cur;
},0); //注意这里设置了初始值
console.log(arr, sum);
打印结果
0 1 0
1 2 1
3 3 2
6 4 3
[1,2,3,4] 10
以上例子中设置了 初始值,index 是从 0 开始, 第一次的 prev 值是设置的初始值 0,数组长度4, reduce函数循环了 4 次
* 结论:如果没有提供 initialValue,reduce 会从索引 1 的地方开始执行 callback 方法, 跳过第一个索引。如果提供 initialValue,从索引 0 开始
-
如果数组为空
3.1 没有给定初始值
var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; }) //报错,"TypeError: Reduce of empty array with no initial value"3.2 给定初始值
var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; },0) console.log(arr, sum); // [] 0* 一般来说我们提供初始值通常更安全
-
简单用法
4.1 数组求和,求乘积
let arr = [1, 2, 3, 4]; let sum = arr.reduce((x,y)=>x+y); let mu1 = arr.reduce((x,y)=>x*y); console.log(sum); // 求和 10 cosole.log(mu1); // 求乘积 24 -
高级用法
5.1 计算数组中每个元素出现的次数
let names = ['zhangsan', 'lisi', 'wangwu', 'zhaoliu', 'zhangsan']; let nameNum = names.reduce((prev,cur) => { if(cur in prev){ prev[cur] ++; }else{ prev[cur] = 1; } return prev; },{}); console.log(nameNum); // {zhangsan: 2, lisi: 1, wangwu: 1, zhaoliu: 1}5.2 数组去重
let arr = [1, 2, 3, 4, 4, 1]; let newArr = arr.reduce((prev,cur)=>{ if(!prev.includes(cur)){ return prev.concat(cur); }else{ return prev; } },[]); console.log(newArr); // [1,2,3,4]5.3 将二维数组转化为一维
let arr = [[0,1], [2,3], [4,5]]; let newArr = arr.reduce((prev,cur)=>{ return prev.concat(cur); },[]); console.log(newArr); // [0,1,2,3,4,5]5.4 将多维数组转化为一维
let arr = [[0,1], [2,3], [4, [5,6,7]]]; /*const newArr = function(arr){ return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[]) }*/ const newArr = (arr) => arr.reduce((prev,cur) => prev.concat(Array.isArray(cur) ? newArr(cur) : cur),[]); console.log(newArr(arr)); //[0,1,2,3,4,5,6,7]5.5 对象里的属性求和
let result = [ { subject: 'math', score: 10 }, { subject: 'chinese', score: 20 }, { subject: 'english', score: 30 } ]; let sum = result.reduce((prev,cur)=>{ return cur.score + prev; },0); console.log(sum); // 60