javascript - JavaScript - 递归构建树形数据结构
问题描述
我有一个名为 tree 的函数,它接受对象数组(作为数据库中的数据字段)和字符串数组作为键。该函数循环遍历 rowsArray 并基于 keyArray 递归地创建具有嵌套属性的对象。
const tree = (rowsArray, keysArray) => {
return rows.reduce((acc, row) => {
const groupBy = (row, keys,) => {
const [first, ...rest] = keys;
if (!first) return [row];
return {
[row[first]]: groupBy(row, rest),
}
};
acc = {...groupBy(row, keys), ...acc};
return acc;
}, {});
}
数据如下:
const data = [{
ID: 1,
Main: "Financial",
Sub: "Forecasts",
Detail: "General"
}, {
ID: 2,
Main: "Financial",
Sub: "HR",
Detail: "Headcount"
}];
const result1 = tree(data, ["Main", "Sub", "Detail"]);
console.log(result1);
当我记录结果时,我得到:
/*
// actual output
{
Financial: {
Forecasts: {
General: [Array]
}
}
}
鉴于,我想得到以下信息:
// expected
{
Financial: {
Forecasts: {
General: [Array]
},
HR: {
Headcount: [Array]
}
}
}
*/
问题是,主函数中的 acc 变量被覆盖,我得到了新对象,而不是累积的,我不太确定如何递归地构建这个对象。我试图将 acc 的实例传递给 groupBy 函数(以记住以前的结果),但没有运气。
您知道如何重写树函数或 groupBy 函数来实现我的目标吗?谢谢!
解决方案
你可以这样做:
function tree(rows, keys) {
return rows.reduce( (acc, row) => {
keys.reduce( (parent, key, i) =>
parent[row[key]] = parent[row[key]] || (i === keys.length - 1 ? [row] : {})
, acc);
return acc;
}, {});
}
const data = [{ID: 1,Main: "Financial",Sub: "Forecasts",Detail: "General"}, {ID: 2,Main: "Financial",Sub: "HR", Detail: "Headcount" }];
const result1 = tree(data, ["Main", "Sub", "Detail"]);
console.log(result1);
请注意,扩展语法会产生浅拷贝。相反,在这个解决方案中,累加器被传递给内部reduce
。所以我们实际上将新行的分层数据合并到现场的累加器中。
推荐阅读
- node.js - 没有调用 jest + supertest 异步回调
- sql - 需要在 Vertica 中将所有空值替换为“0”
- python - 逗号作为小数分隔符 Python
- c# - 在表达式中使用 LINQ Any
- angular - 寻找下拉菜单(可能是一个框架)
- kotlin - 检查匿名对象的实例
- python - 如何解决此不和谐声音 Bot 错误?
- javascript - 如何将 Blob 对象转换为文件并将其发送到服务器
- reactjs - React Typescript:MuiAccordion OnChange 事件处理程序类型错误
- ios - 为什么OC数组中会出现空对象?