按对象ID过滤巢状树对象 [英] filter nest tree object by object id

查看:64
本文介绍了按对象ID过滤巢状树对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像下面这样的树对象:

I have a tree object like below:

let data = [
  {
    id: 1,
    children: [
     {
      id: 1.1,
      children: [
       {
        id: 1.2,
        children: []
       },
       {
        id: 1.22,
        children: []
        }
      ]
     }
    ]
  },
  {
   id: 2,
   children: []
  }
]

我想过滤掉等于特定值的id.在这种情况下,我要过滤掉等于 1.2 的ID.

I want to filter out id equal a specific value. In this case, I want to filter out id equal 1.2.

我想要的鲁is如下:

let data = [
  {
    id: 1,
    children: [
     {
      id: 1.1,
      children: [
        {
         id: 1.22,
         children: []
        }
      ]
     }
    ]
  },
  {
   id: 2,
   children: []
  }
]

我已经搜索了一些有关过滤器嵌套深层对象的问题,但仍然不知道如何做.我需要使用递归来解决这个问题.

I have search a few question about filter nest deep object, But still don't know how. I need to use recursion to solve this.

这是我的方式:

function handleDelete (data) {
 return data.filter(t => {
   if (t.children.length) {
     handleDelete(t.children)
    })
   } else {
     return t.id !== '1.2'
  }
})
}
let result = handleDelete(data)

推荐答案

删除节点及其后代

这是使用flatMap和相互递归 1 -

  1. del接受节点的数组t,查询q,并在每个具有查询的节点上调用del1
  2. del1接受一个单个节点t,一个查询q,并在该节点的子节点上调用del
  1. del accepts an array of nodes, t, a query, q, and calls del1 on each node with the query
  2. del1 accepts a single node, t, a query, q, and calls del on a node's children

const del = (t, q) =>
  t.flatMap(v => del1(v, q))                  // <-- 1

const del1 = (t, q) =>
  q == t.id
    ? []
    : { ...t, children: del(t.children, q) }  // <-- 2

const data =
  [{id:1,children:[{id:1.1,children:[{id:1.2,children:[]},{id:1.22,children:[]}]}]},{id:2,children:[]}]

const result =
  del(data, "1.2")

console.log(result)

在输出中,我们看到删除了node.id 1.2-

In the output, we see node.id 1.2 is removed -

[
  {
    "id": 1,
    "children": [
      {
        "id": 1.1,
        "children": [
          {
            "id": 1.22,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "children": []
  }
]


保留后代

在上面的程序中,如果node.id与我们的查询匹配,则删除该节点及其后代子节点的 all .如果我们只想删除父节点并保留子节点,则可以对程序进行单个修改(!)-

In the program above, if a node.id matches our query, the node and all of its descendent children are removed. If we only want to delete the parent node and keep the children, we can make a single modification (!) to the program -

const del = (t, q) =>
  t.flatMap(v => del1(v, q))

const del1 = (t, q) =>
  q == t.id
    ? del(t.children, q)                      // <-- !
    : { ...t, children: del(t.children, q) }

const data =
  [{id:1,children:[{id:1.1,children:[{id:1.2,children:[]},{id:1.22,children:[]}]}]},{id:2,children:[]}]

const result =
  del(data, "1")     // <-- delete node.id equal to "1"

console.log(result)

注意1的子代仍如何包含在输出中-

Notice how the children for 1 are still included in the output -

[
  {
    "id": 1.1,
    "children": [
      {
        "id": 1.2,
        "children": []
      },
      {
        "id": 1.22,
        "children": []
      }
    ]
  },
  {
    "id": 2,
    "children": []
  }
]


没有相互递归

相互递归不是唯一的方法,但它是避免动态类型检查的唯一方法,例如下面的方法.在此最终修订版中,我们删除了父级及其所有子级,就像在第一个程序中一样,但是此del是使用单个递归函数-

Mutual recursion isn't the only way to do it, but it's the only way to avoid a dynamic type check, such as the one below. In this final revision, we remove a parent and all of its children, as we did in the first program, but this del is implemented using a single recursive function -

const del = (t, q) =>
  Array.isArray(t)                             // <-- array
    ? t.flatMap(v => del(v, q))
: Object(t) === t                              // <-- object
    ? q == t.id
      ? []
      : { ...t, children: del(t.children, q) }
: t                                            // <-- neither (noop)


const data =
  [{id:1,children:[{id:1.1,children:[{id:1.2,children:[]},{id:1.22,children:[]}]}]},{id:2,children:[]}]

const result =
  del(data, "1.2")

console.log(result)

输出与第一个程序相同,其中删除了1.2和所有后代-

The output is the same as the first program, where 1.2 and all descendants are removed -

[
  {
    "id": 1,
    "children": [
      {
        "id": 1.1,
        "children": [
          {
            "id": 1.22,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "children": []
  }
]


1.参见此相关问题与解答.
2.此答案中的所有程序都产生一棵新树.原始输入没有被del(或del1)修改.


1. See this technique used on a different data set in this related Q&A.
2. All programs in this answer produce a new tree. The original input is not modified by del (or del1).

这篇关于按对象ID过滤巢状树对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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