![](/img/trans.png)
[英]Recursively filter an array of infinitely nested objects by mutliple matching conditions but only return parent that has an instance of both matches
[英]Filter nested array by matching keywords in both parent or child
我需要通過匹配關鍵字來過濾嵌套數組。 它必須返回與父級或其子項之一的name屬性匹配的所有對象,並且還要過濾其子項。
例:
[
{
"name": "abc",
"children": [
{ "name": "abcd" },
{ "name": "efg" }
]
},
{
"name": "hjk",
"children": [
{ "name": "lmn" },
{ "name": "opq" }
]
},
{
"name": "xyz",
"children": [
{ "name": "lmn" },
{ "name": "abcdef" }
]
}
]
如果文本輸入為“ ab”,則它必須返回:
[
{
"name": "abc",
"children": [
{ "name": "abcd" }
]
},
{
"name": "xyz",
"children": [
{ "name": "abcdef" }
]
}
]
(它與父項或至少一個子項匹配,並返回,但父項和子項除外)
現在,我只能像這樣過濾父母:
filteredArray = _.filter(array, (parent) => {
return _.includes(_.toLower(parent.name), _.toLower(filterText));
});
我該如何修改它以便也過濾孩子?
編輯:父級可以有空或沒有子級數組。
恕我直言,您可以使用Array#reduce()
方法執行以下操作:
arr = [{"name":"abc","children":[{"name":"abcd"},{"name":"efg"}]},{"name":"hjk","children":[{"name":"lmn"},{"name":"opq"}]},{"name":"xyz","children":[{"name":"lmn"},{"name":"abcdef"}]}, {"name": "xyz"}] var input = "ab" filteredArr = arr.reduce((accum, ele) => { var obj = {}; ele['children'] && ele['children'].forEach(e => { if (e['name'].includes(ele['name']) || e['name'].includes(input)) { obj['name'] = ele['name']; obj['children'] ? (obj['children'].push(e)) : (obj['children'] = [], obj['children'].push(e)) } }) if (Object.keys(obj).length > 0) accum.push(obj); return accum; }, []) console.log(filteredArr);
對於每個元素,請檢查名稱並過濾其子元素,如果其中一個為真,則將具有已過濾子元素的元素推入新數組
const data = [{"name": "abc", "children": [{ "name": "abcd" }, { "name": "efg" } ] }, {"name": "hjk","children": [{ "name": "lmn"}, { "name": "opq" } ]}, { "name": "xyz","children": [{ "name": "lmn" },{"name": "abcdef" } ] }, {"name": "abc"}, {"name": "abc", children: []}]; const res = data.reduce((acc, a) => { const ch = a.children && a.children.filter(b => b.name.includes('ab')); if(ch && ch.length) acc.push({...a, children: ch}); else if(a.name.includes('ab')) acc.push({ name: a.name }); return acc; }, []); console.log(res);
lodash
並沒有真正的需要。 #nodash! 只是現代香草JS:
const regExp = new RegExp(filterText, 'i');
const result = array.reduce((acc, { name, children = [] }) => {
const next = children.filter(child => child.name.match(regExp));
if (name.match(regExp) || next.length > 0) {
acc.push({ name, children: next });
}
return acc;
}, []);
如果未找到子字符串,則name.match(regExp)
將返回null
。
children = []
處理parent
沒有孩子的情況。
另外,請注意,使用RegExp檢查子字符串應該比執行多次轉換和查找(例如toLower
, includes
)要快得多。
var arrayList = [
{
"name": "abc",
"children": [
{ "name": "abcd" },
{ "name": "efg" }
]
},
{
"name": "ab",
"children": [
{ "name": "lmn" },
{ "name": "opq" }
]
},
{
"name": "jdfj",
"children": [
{ "name": "lmn" },
{ "name": "abcdef" }
]
}
];
function filterArray(arrayList, search){
return arrayList.filter((item) => {
let childrens = item.children;
if(childrens && childrens.length){
item.children = filterArray(childrens, search);
if(item.children && item.children.length){
return true;
}
}
return item.name.indexOf(search) > -1;
});
}
const filter = filterArray(arrayList, 'ab');
console.log(filter);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.