我正在嘗試根據正確匹配的陣列從嵌套陣列中洗掉專案。
適用三個要求:
- 陣列的深度未知。項可以有嵌套的子項。
- 只應移除沒有孩子的物品
- 如果專案不在匹配的陣列中,則應洗掉它們
我已經構建了一個函式來遞回地到達最深層次并根據 $match 陣列過濾專案。
這是我的代碼到目前為止的樣子:
import * as lodash from "https://cdn.skypack.dev/[email protected]";
let filterRecursively = (arr, match) => {
// Recursively go to the deepest array we can find
arr.forEach(el => {
arr = el.children ? filterRecursively(el.children, match) : arr
});
// If we are at the deepest level we filter the items ...
if (arr[0] && arr[0].children === undefined) {
return _.filter(arr, (item) => {
return match.includes(item.name)
})
} else { // ... if not we just return the array as-is
return arr
}
}
let arr = [
{
'name': 'John',
'children': [
{
'name': 'John',
'children': [
{ 'name': 'John' },
{ 'name': 'Jane' },
{ 'name': 'Joe' }
]
}]
}, {
'name': 'Jeff',
'children': [
{
'name': 'Joe',
'children': [
{ 'name': 'Jill' },
{ 'name': 'Jeff' },
{ 'name': 'Joe' }
]
}]
}];
let match = ['John', 'Joe'];
let result = filterRecursively(arr, match);
console.log(result);
// Expected result:
[
{
'name': 'John',
'children': [
{
'name': 'John',
'children': [
{ 'name': 'John' },
{ 'name': 'Joe' }
]
}]
}, {
'name': 'Jeff',
'children': [
{
'name': 'Joe',
'children': [
{ 'name': 'Joe' }
]
}]
}];
// Current output
[
{
"name": "Joe"
}
]
見 Codepen
uj5u.com熱心網友回復:
let filterRecursively = (arr, match) => {
// Recursively go to the deepest array we can find
return arr
.map((el) =>
el.children
? { ...el, children: filterRecursively(el.children, match) }
: el
)
.filter((el) => el.children || match.includes(el.name));
};
我已經更新了過濾器遞回。
let filterRecursively = (arr, match) => {
// Recursively go to the deepest array we can find
return arr
.map((el) =>
el.children
? { ...el, children: filterRecursively(el.children, match) }
: el
)
.filter((el) => el.children || match.includes(el.name));
};
let arr = [
{
name: "John",
children: [
{
name: "John",
children: [{ name: "John" }, { name: "Jane" }, { name: "Joe" }],
},
],
},
{
name: "Jeff",
children: [
{
name: "Joe",
children: [{ name: "Jill" }, { name: "Jeff" }, { name: "Joe" }],
},
],
},
];
let match = ["John", "Joe"];
let result = filterRecursively(arr, match);
console.log(JSON.stringify(result));
// Expected result:
// [
// {
// 'name': 'John',
// 'children': [
// {
// 'name': 'John',
// 'children': [
// { 'name': 'John' },
// { 'name': 'Joe' }
// ]
// }]
// }, {
// 'name': 'Jeff',
// 'children': [
// {
// 'name': 'Joe',
// 'children': [
// { 'name': 'Joe' }
// ]
// }]
// }];
uj5u.com熱心網友回復:
我認為最好從檢查名稱的代碼中分離出適當處理子節點的通用節點過濾技術。這里filterNodes
接受一個謂詞,表示是否應該包含節點(不用擔心孩子)。然后它會處理孩子。
我們只通過傳遞一個謂詞來測驗名稱是否在允許串列中來撰寫我們的 main 函式。
在一起,它看起來像這樣:
const filterNodes = (pred) => (nodes) =>
nodes .flatMap (
(node, _, __,
kids = filterNodes (pred) (node .children || [])
) => pred (node) || node .children ?.length > 0
? [{...node, ... (kids .length ? {children: kids} : {})}]
: []
)
const removeUnmatchedNames = (names) =>
filterNodes (({name}) => names .includes (name))
const arr = [{name: "John", children: [{name: "John", children: [{name: "John"}, {name: "Jane"}, {name: "Joe"}]}]}, {name: "Jeff", children: [{name: "Joe", children: [{name: "Jill"}, {name: "Jeff"}, {name: "Joe"}]}]}]
console .log (removeUnmatchedNames (['John', 'Joe']) (arr))
.as-console-wrapper {max-height: 100% !important; top: 0}
uj5u.com熱心網友回復:
因為forEach
基本上“跳過”層而不回傳任何內容,所以你最終得到的只是你的第一個也是最深的結果。
我還認為您的函式有點復雜,因為它以陣列而不是某種ROOT
節點開頭。
這是(我認為)滿足您要求的替代方案:
let childlessMatch = (node, match) => {
// If it's at the deepest level, check against match
if (node.children === undefined) {
return match.includes(node.name) ? [node] : [];
}
// If not, calculate the next child layer first
const newChildren = node.children.flatMap(c => childlessMatch(c, match));
// With the children calculated, we can prune based on whether there
// are any children left to show
if (newChildren.length === 0) return [];
return [{
...node,
children: newChildren
}]
}
在一個可運行的片段中:
顯示代碼片段
let childlessMatch = (node, match) => {
if (node.children === undefined) {
return match.includes(node.name) ? [node] : [];
}
const newChildren = node.children.flatMap(c => childlessMatch(c, match));
if (newChildren.length === 0) return [];
return {
...node,
children: newChildren
}
}
let arr = [
{
'name': 'John',
'children': [
{
'name': 'John',
'children': [
{ 'name': 'John' },
{ 'name': 'Jane' },
{ 'name': 'Joe' }
]
}]
}, {
'name': 'Jeff',
'children': [
{
'name': 'Joe',
'children': [
{ 'name': 'Jill' },
{ 'name': 'Jeff' },
{ 'name': 'Joe' }
]
}]
}];
let match = ['John', 'Joe'];
let result = childlessMatch({ children: arr }, match).children;
console.log(result);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/486359.html
標籤:javascript 数组 递归 嵌套的 罗达什
上一篇:是什么導致無限遞回?(序言)