按对象ID过滤巢状树对象 [英] filter nest tree object by object 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 -
-
del
接受节点的数组,t
,查询q
,并在每个具有查询的节点上调用del1
-
del1
接受一个单个节点t
,一个查询q
,并在该节点的子节点上调用del
del
accepts an array of nodes,t
, a query,q
, and callsdel1
on each node with the querydel1
accepts a single node,t
, a query,q
, and callsdel
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屋!