【问题标题】:How replace item in tree recursively如何递归替换树中的项目
【发布时间】:2020-06-04 02:23:06
【问题描述】:

我正在尝试创建一棵树。但我不知道如何在树中递归替换项目。

我有一个项目数组,每个项目如果在顶部 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":[

            ]
         }
      ]
   }
]

【问题讨论】:

  • 你能告诉我们你到目前为止的努力吗?
  • 当然,我已经编辑了问题
  • 一小组样本数据也很有帮助。恐怕它的图片没有多大帮助。
  • 请考虑编辑此处的代码以构成一个minimal reproducible example,适合放入像The TypeScript Playground 这样的独立IDE。现在有未定义/未声明变量的错误。如果您不询问这些错误,请添加(或最好删除)代码以使它们消失。祝你好运!

标签: javascript typescript recursion


【解决方案1】:

我认为你可以在这里做一个相当简单的递归。我用非常少的数据集进行测试。节点有ids、titles,有时还有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}

请注意,此代码不会在第一次匹配时停止搜索。它检查所有内容并替换 all 匹配项。我不知道这对你来说是否可以接受。

这个版本是用纯 Javascript 编写的。我把打字稿打字留给你。 (因为我当然不想这样做!)

【讨论】:

  • 完美!!多谢!! ...现在我要尝试递归地插入一个项目
  • export const addBranchInTree = ( 分支:任意,分支:IBranch ): Array => { return Array.isArray(branchs) ?分支.map((o:IBranch)=> addBranchInTree(o,分支)):分支.children.push(分支); };你认为递归添加什么?
  • 它可能会起作用。您必须进行测试,而在评论中查看未格式化的代码并不是我的强项之一!
  • 似乎缺少一些东西来测试 where 添加元素。你如何决定?但实际上,如果您对此感到困惑,那可能应该是一个新问题,而不是一系列 cmets。
猜你喜欢
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 2011-01-07
  • 2015-10-18
  • 1970-01-01
  • 2010-12-07
  • 2018-12-29
相关资源
最近更新 更多