javascript - 如何递归替换树中的项目
问题描述
我正在尝试创建一棵树。但我不知道如何在树内递归替换项目。
我有一个项目数组,每个项目如果在顶部 parentId 是未定义的,如果有 clindren,每个孩子都有一个 parentId 属性,显示他的父母如何。
我正在尝试创建一种方法来在 children 属性中找到该项目,该项目可以具有 1 个或多个级别。
如果它可能返回更新的数组
这是我的代码:
const onChangeStatusEditable = () => {
const updatedBranch: IBranch = Object.assign({}, branch, {
editable: !editable,
});
let updatedBranchs: Array<IBranch> = [];
if (parentId === undefined) {
const index = branchs.findIndex( (b: IBranch) => b.id === branch.id);
updatedBranchs = Object.assign([], branchs, {
[index]: updatedBranch,
});
onUpdateBranchs(updatedBranchs);
} else {
// EDIT: efforts
I'm tryin with this recursive method
}
};
// EDIT
export const replaceBranch = (branchs: Array<IBranch>, branch: IBranch): Array<IBranch> => {
let updated: Array<IBranch> = [];
branchs.forEach((b: IBranch) => {
if (b.children) {
updated = replaceBranch(b.children, branch);
if (updated) {
return updated;
}
}
if (b.id === branch.id) {
const index: number = branchs.findIndex((c: IBranch) => c.id === branch.id);
b.children[index] = branch;
updated = b.children;
console.log("founded: ", b);
return updated;
}
});
return updated;
};
IBrach 有这个接口:
export interface IBranch {
id: number;
parentId: number | undefined;
active: boolean;
favorite: boolean;
title: string;
editable: boolean;
level: number;
checkbox: boolean;
checkboxEnabled: boolean;
children: Array<any>;
}
数据:
[
{
"id":0,
"active":false,
"favorite":false,
"level":0,
"title":"New Branch 0",
"editable":false,
"checkbox":false,
"checkboxEnabled":false,
"children":[
{
"id":1,
"parentId":0,
"active":false,
"favorite":false,
"level":1,
"title":"New Branch 1",
"editable":false,
"checkbox":false,
"checkboxEnabled":false,
"children":[
]
}
]
}
]
解决方案
我认为你可以在这里做一个相当简单的递归。我用非常少的数据集进行测试。节点有id
s、title
s,有时还有children
。但我认为这足以表明行为。
const updateElement = (obj, el) =>
Array .isArray (obj)
? obj .map (o => updateElement (o, el))
: obj .id === el .id
? el
: // else
{...obj, ...(obj .children ? {children: updateElement (obj .children, el)} : {})}
const data = [
{id: 1, title: 'foo', children: [
{id: 11, title: 'bar'},
{id: 12, title: 'baz', children: [
{id: 121, title: 'qux'},
{id: 122, title: 'quz'}
]},
{id: 13, title: 'corge'}
]},
{id: 2, title: 'grault'}
];
const newItem = {id: 121, title: 'new title here', and: 'more props'}
console .log (
updateElement (data, newItem)
)
.as-console-wrapper {min-height: 100% !important; top: 0}
请注意,此代码不会在第一次匹配时停止搜索。它检查所有内容并替换所有匹配项。我不知道这对你来说是否可以接受。
这个版本是用纯 Javascript 编写的。我把打字稿打字留给你。(因为我当然不想这样做!)
推荐阅读
- c# - OWIN self 主机连接频繁掉线
- kubernetes - cronjob Kubernetes 使用应用程序和云代理容器的预期行为
- python - 如何将自动生成的注册 ID 更改/分配给 microsoft azure 认知说话者识别 API 中的特定人员姓名
- java - 线程“main”java.lang.Error 中的异常:未解决的编译问题(Edx 课程示例)
- java - 当'e'对于非常大的e是十进制时,如何对e求幂?
- amazon-web-services - AWS SAM YAML - 多次附加相同的策略,或在相同的 DynamoDB 策略上附加多个表
- ios - 从xcode中的注释映射访问结构参数
- java - SpringBoot程序中如何为mysql动态设置sql_mode?
- mysql - 使用 phpmyadmin 运行时插入查询语法错误
- r - 使用 rstanarm 包中的 stan_aov 缺少预测变量计算贝叶斯方差分析