如何在树中递归插入项目 [英] How insert item in tree recursively

查看:22
本文介绍了如何在树中递归插入项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个树组件.但我不知道如何在树中递归插入项目.

I'm trying to create a tree component. But I dont know how insert a item recursively inside a tree.

每个项目都是动态创建的,我想在每个级别插入/创建树的项目/​​分支.问题是当我无法在第 3 级插入项目时.

Each item its created dinamically and I would like instert/create an item/branch of the tree in each level. Problem is that when I cant insert items on level 3.

例如,我生成了以下代码:

For example, I have this code generated:

[{
    "id": 0,
    "active": false,
    "favorite": false,
    "level": 0,
    "title": "New Branch 0",
    "editable": false,
    "checkbox": false,
    "checkboxEnabled": false,
    "children": []
}, {
    "id": 1,
    "active": false,
    "favorite": false,
    "level": 0,
    "title": "New Branch 1",
    "editable": false,
    "checkbox": false,
    "checkboxEnabled": false,
    "children": [{
        "id": 3,
        "parentId": 1,
        "active": false,
        "favorite": false,
        "level": 1,
        "title": "New Branch 3",
        "editable": false,
        "checkbox": false,
        "checkboxEnabled": false,
        "children": []
    }, {
        "id": 4,
        "parentId": 1,
        "active": false,
        "favorite": false,
        "level": 1,
        "title": "New Branch 4",
        "editable": false,
        "checkbox": false,
        "checkboxEnabled": false,
        "children": []
    }]
}, {
    "id": 2,
    "active": false,
    "favorite": false,
    "level": 0,
    "title": "New Branch 2",
    "editable": false,
    "checkbox": false,
    "checkboxEnabled": false,
    "children": []
}]

而且我正在尝试创建一个插入方法,例如在 New Branch 4 的孩子或其孩子的内部.然后返回更新的数组.

And I'm trying to create a method that insert, for example inside children of New Branch 4 or his children. And that return updated array.

这是我的代码:

const onCreateChildren = () => {
    let newBranch: IBranch = generateBranch(numBranchs);
    newBranch = Object.assign({}, newBranch, {
        level: level + 1,
        parentId: branch.id,
    });
    let copyChildren: Array<IBranch> = children.slice();
    copyChildren.push(newBranch);
    const updatedBranch: IBranch = Object.assign({}, branch, {
        children: copyChildren,
    });
    if (parentId === undefined) {
        const index: number = branchs.findIndex( (b: IBranch) => b.id === branch.id);
        const updatedBranchs: Array<IBranch> = Object.assign([], branchs, {
            [index]: updatedBranch,
        });
        onUpdateBranchs(updatedBranchs);
    } else {
        const updatedBranchs: any = addBranchInTree(branchs, newBranch);
        onUpdateBranchs(updatedBranchs);
    }

    onUpdateNumBranchs(numBranchs+1);
};

为什么总是有效??有人能帮我吗??其他想法??

Why doenst work always?? Can someone help me?? Other ideas??

export const addBranchInTree = (branchs: any, branch: IBranch): any => {
    return Array.isArray(branchs)
        ? branchs.map((o: IBranch) => addBranchInTree(o, branch))
        : findNode(branchs, branch);
};

const findNode = (branchs: any, branch: any): any => {
    if (branchs.children.length > 0) {
        branchs.children.forEach((child: any) => {
            return findNode(child, branch);
        });
    }

    if (!Array.isArray(branchs)) {
        if (branchs.parentId === branch.parentId - 1) {
            return branchs.children.push(branch);
        }
    }

    return branchs;
};

推荐答案

类似于我们在之前的问题中的做法,我们可以递归遍历对象,查找 id 与我们的新项目的 parentId 匹配的项目,并将新元素附加到其子元素列表中.

Similarly to how we did it in an earlier question, we can recursively traverse the object, looking for the item whose id matches our new item's parentId and append the new element to its list of children.

处理一个没有 parentId 的项目有一点额外的复杂性,我假设它应该在根上.本质上,如果我们在一个数组中并且我们的元素没有 parentId,我们假设我们可以附加它.如果原始数据是数组,这应该只发生在根上.

There is a little extra complexity in dealing with an item that has no parentId, which I'm assuming should go on the root. Essentially, if we're in an array and our element has no parentId, we assume we can just append it. This should only happen on the root, if the original data is an array.

const addElement = (obj, el) => 
  Array .isArray (obj) 
    ? 'parentId' in el 
      ? obj .map (o => addElement (o, el))
      : [...obj, el]
  : obj .id === el .parentId 
    ? {...obj, children: [...(obj.children || []), el]}
  : // else
    {...obj, ...('children' in obj ? {children: addElement (obj.children, el)} : {})}

const data = [
  {id: 1, title: 'foo', children: [
    {id: 11, parentId: 1, title: 'bar',},
    {id: 12, parentId: 1, title: 'baz', children: [
      {id: 121, parentId: 12, title: 'qux'},
      {id: 122, parentId: 12, title: 'quz'}
    ]},
    {id: 13, parentId: 1, title: 'corge'}
  ]},
  {id: 2, title: 'grault'}
];

const newItem = {id: 123, parentId: 12, title: 'new element here'}
console .log (addElement (data, newItem))

const motherlessChild = {id: 99, title: 'root element here -- no parentId'}
console .log (addElement (data, motherlessChild))

.as-console-wrapper {min-height: 100% !important; top: 0}

注意(我没有在前面的问题中指出这一点)这不会改变您的数据对象,而是返回一个全新的对象.我们也不处理新元素没有 parentId 的情况,或者树不包含具有与新元素的 匹配的 id 的元素父 ID.这些留给读者作为练习.

Note (and I didn't point this out on the earlier question) that this does not mutate your data object, returning instead an entirely new one. We also don't deal with the case that the new element has no parentId, or that the tree does not include an element with an id matching the new element's parentId. Those are left as exercises for the reader.

上面使用的匹配——检查 id 是否与新元素的 parentId 匹配——不正确,你能解释一下你想如何找到正确的请点插入,好吗?

It the matching used above -- checking that the id matches the new element's parentId -- is not correct, could you explain how you do want to find the correct spot to insert it, please?

另外一点,请将此视为有意的建设性批评:您已经使用 StackOverflow 有一段时间了.如果您还没有阅读帮助中心关于创建最小的、可重现的示例,请这样做.上面似乎有太多与您提出的问题无关的代码.特别注意您的样本数据.我希望你能从我之前的回答中得到这个想法,但你似乎没有.您应该能够使用具有 idparentIdchildren 的相关节点来描述这个问题,并且只有一个属性可以证明那些在别处没有特别注明的部分(我使用了 title,但任何事情都可以.)当无关内容被删除后,回答问题会容易得多.

One other point, and please take this as the constructive criticism that's intended: You've been around StackOverflow for a while. If you haven't read the help center's discussion on creating a minimal, reproducible example, please do so. It seems there is too much code above unrelated to the question you're asking. Especially note your sample data. I was hoping you might get the idea from my earlier answer, but it seems you didn't. You should be able to describe this problem with nodes that have an id, a parentId, children where relevant, and only one more property to demonstrate those parts that aren't specifically noted elsewhere (I used title, but anything would do.) It makes it much easier to answer questions when the extraneous matter has been removed.

这篇关于如何在树中递归插入项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆