1、递归求和。
数据类型举例:
const A = [ { children: [ { children: [ { children: [ { width: 20, }, { width: 30, }, { width: 20, }, ], }, ], }, ], }, { width: 30, }, { children: [ { width: 10, }, { width: 30, }, ], },]求宽度之和
// 计算表格列宽总和
const sumColumn = arr => (arr.reduce((acc, cur) => (
Number(acc + (cur.children && cur.children.length ? sumColumn(cur.children) : cur.width))), 0)
);
sumColumn(A)结果为140;
2、拍平对象数组
数据举例:
同1例
拍平函数:
function flattenArrayss(arr) {
return arr.reduce((acc, current) => {
if (current.children && current.children.length) {
return [...acc, current, ...flattenArrayss(current.children)];
}
return [...acc, current];
}, []);
}
拍平结果:
flattenArrayss(A);
3、根据末端节点找到所有父节点
比如找到focus为'5'的节点,及其所有父节点,用->相连接
数据举例:
同1例
解决函数:
const findTopParents = (array, label) => {
let stackTitle = [];
let going = true;
const walker = (a, b) => {
a.forEach((item) => {
if (!going) return;
stackTitle.push(item.focus);
if (item.focus === b) {
going = false;
} else if (item.children) {
walker(item.children, label);
} else {
stackTitle.pop();
}
});
if (going) {
stackTitle.pop();
}
};
walker(array, label);
const lgth = stackTitle.length - 1;
stackTitle = lgth ? `${stackTitle[lgth]}(${stackTitle.slice(0, lgth).join('->')})` : stackTitle.join('');
return stackTitle;
};
运行结果:
findTopParents(A, '5');
"5(1->2->3)"
4、根据末节点的值找到其所在对象其他元素的值
比如找到focus为'5'的节点,然后输出所在节点width的值
数据举例:
解决函数:
const findChildrenId = (id, list) => {
let allow = 1;
const walker = (a, b) => {
for (let i = 0; i < b.length; i++) {
if (b[i].focus === a) {
allow = b[i].width;
return;
} else if (b[i].children && b[i].children.length > 0) {
walker(a, b[i].children);
}
}
};
walker(id, list);
return allow;
};
运行结果:
findChildrenId('5',A);
30
5、数组元素合并
数据举例
"responseParamList": [
{
"id": 1,
"parentId": 0,
"childrenNum": 4,
"paramName": "goods_search_response",
"paramType": "OBJECT",
"sourcePath": null,
"example": "",
"paramDesc": "response"
}, {
"id": 2,
"parentId": 1,
"childrenNum": 55,
"paramName": "goods_list",
"paramType": "OBJECT[]",
"sourcePath": null,
"example": "",
"paramDesc": "商品列表"
}, {
"id": 3,
"parentId": 2,
"childrenNum": 0,
"paramName": "activity_tags",
"paramType": "INTEGER[]",
"sourcePath": null,
"example": "",
"paramDesc": "商品活动标记数组"
}, {
"id": 4,
"parentId": 2,
"childrenNum": 0,
"paramName": "activity_tags",
"paramType": "INTEGER[]",
"sourcePath": null,
"example": "",
"paramDesc": "商品活动标记数组,例:[4,7]"
}, , {
"id": 5,
"parentId": 0,
"childrenNum": 0,
"paramName": "activity_tags",
"paramType": "INTEGER[]",
"sourcePath": null,
"example": "",
"paramDesc": "商品活动标记数组,例:[4,7],4-秒杀 7-ss等"
},
]
解决方法:
const mergeData = (list: any[]) => {
let data = list
data.forEach(ele => {
// 第一次forEach遍历到所有的数组对象,不做去重,数组依旧拥有6个元素
let parentId = ele.parentId
if (parentId === 0) {
//是根元素的hua ,不做任何操作,如果是正常的for-i循环,可以直接continue.
} else {
//如果ele是子元素的话 ,把ele扔到他的父亲的child数组中.它的父元素也可能是别人的子元素
//遍历6遍,数组依旧拥有6个元素,只不过有些有嵌套关系
data.forEach(d => {
if (d.id === parentId) {
let childArray = d.children
// 一则避免了去给d.child声明定义空数组
// childArray为undefined时,用push方法去报undefined.push的错
if (!childArray) {
childArray = []
}
// 用push保证同级别的对象有序追加
childArray.push(ele)
d.children = childArray
} //else的地方不做处理,保证了最深层的对象没有child属性
})
}
})
//去除重复元素
data = data.filter(ele => ele.parentId === 0)
return data
}