【问题标题】:How filter in a nested tree object without losing structure in javascript?如何过滤嵌套树对象而不丢失javascript中的结构?
【发布时间】:2019-12-04 16:54:58
【问题描述】:

为了在 React 中正确显示树视图,我需要过滤一个嵌套的树对象。

我找到了这篇文章: filter nested tree object without losing structure

但实际上我想做完全相反的事情。 例如,如果在我的 filterData 函数 name === "a3" 我想用 name === "a3" 保留对象

const result = filterData(items, "a3")
const items = [
  {
    name: "a1",
    id: 1,
    children: [
      {
        name: "a2",
        id: 2,
        children: [
          {
            name: "a3",
            id: 3
          },
          {
            name: "a5",
            id: 4
          }
        ]
      }
    ]
  },
  {
    name: "b2",
    id: 2,
    children: [
      {
        name: "a2",
        id: 2,
        children: [
          {
            name: "a3",
            id: 3
          }
        ]
      },
      {
        name: "a4",
        id: 8
      }
    ]
  }
];
const result = [
  {
    name: "a1",
    id: 1,
    children: [
      {
        name: "a2",
        id: 2,
        children: [
          {
            name: "a3",
            id: 3
          }
        ]
      }
    ]
  },
  {
    name: "b2",
    id: 2,
    children: [
      {
        name: "a2",
        id: 2,
        children: [
          {
            name: "a3",
            id: 3
          }
        ]
      }
    ]
  }
];

【问题讨论】:

    标签: javascript json recursion tree


    【解决方案1】:

    您可以在不改变给定数据的情况下创建新对象并减少数组。

    function filter(array, name) {
        return array.reduce((r, { children = [], ...o }) => {
            if (o.name === name) {
                r.push(o);
                return r;
            }
            children = filter(children, name);
            if (children.length) {
                r.push(Object.assign(o, { children }));
            }
            return r;
        }, []);
    }    
    
    var items = [{ name: "a1", id: 1, children: [{ name: "a2", id: 2, children: [{ name: "a3", id: 3 }, { name: "a5", id: 4 }] }] }, { name: "b2", id: 2, children: [{ name: "a2", id: 2, children: [{ name: "a3", id: 3 }] }, { name: "a4", id: 8 }] }];
    
    console.log(filter(items, "a2"));
    console.log(filter(items, "a3"));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 尼娜,你再一次拯救了我的一天!效果很好,现在我必须反复阅读以确保理解您的建议!非常感谢。
    • 非常感谢,实际上,例如result = filter(items, "a2") 它似乎不起作用,下面的级别不会删除。我已经尝试改进您的代码,但我还没有找到解决方案... :( 如果我们采用与上面相同的 items 对象,我的结果应该是:javascript const result = [ { name: "a1", id: 1, children: [ { name: "a2", id: 2, } ] }, { name: "b2", id: 2, children: [ { name: "a2", id: 2, } ] } ];
    • 我明白了,没有找到节点的子节点,请参阅编辑。
    【解决方案2】:

    我刚刚改进了 Nina 的提议,以便在不包含“名称”的情况下删除下面的级别。

    function filter(array, name) {
      return array.reduce((r, o) => {
        var children;
        children = filter(o.children || [], name);
    
        if (children.length) {
          r.push(Object.assign({}, o, { children }));
        }
    
        if (o.name === name) {
          r.push(o);
          if (o.children && o.children.name !== name) {
            r[0].children = [];
          }
        }
    
        return r;
      }, []);
    }
    
    var items = [{ name: "a1", id: 1, children: [{ name: "a2", id: 2, children: [{ name: "a3", id: 3 }, { name: "a5", id: 4 }] }] }, { name: "b2", id: 2, children: [{ name: "a2", id: 2, children: [{ name: "a3", id: 3 }] }, { name: "a4", id: 8 }] }],
    
    result = filter(items, "a2");
    
    console.log(result);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 2023-03-18
      • 2022-01-24
      相关资源
      最近更新 更多