我需要通过匹配关键字来过滤嵌套数组。它必须返回与父或其子对象的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));
});我如何修改它,使它也过滤孩子们?
编辑:父数组可以是空数组,也可以是没有子数组。
发布于 2018-07-25 08:02:22
对于每个元素,检查名称并筛选其子元素,如果其中一个为真,则将带过滤子元素的元素推到新数组中。
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);
发布于 2018-07-25 09:06:57
在lodash中没有真正的需求。#诺德什!只是现代香草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)要快得多。
这是工作的用你的例子。
发布于 2018-07-25 07:57:13
IMHO,您可以使用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);
https://stackoverflow.com/questions/51513293
复制相似问题