我试图根据一些嵌套对象过滤数组。我准备了一些Fiddle
输入数组如下所示:
let arrayOfElements =
[
{
"name": "a",
"subElements":
[
{"surname": 1},
{"surname": 2}
]
},
{
"name": "b",
"subElements":
[
{"surname": 3},
{"surname": 1}
]
},
{
"name": "c",
"subElements":
[
{"surname": 2},
{"surname": 5}
]
}
];
我希望这种情况的输出看起来像这样:
let filteredArray =
[
{
"name": "a",
"subElements":
[
{"surname": 1}
]
},
{
"name": "b",
"subElements":
[
{"surname": 1}
]
}
];
我正在使用这个公式来做到这一点:
let filteredArray = arrayOfElements.filter((element) => element.subElements.some((subElement) => subElement.surname === 1));
输出几乎是好的,但是它返回所有具有姓氏的对象的对象(更好地检查小提琴:D),而不是将它们切掉。我该如何改进过滤?
答案 0 :(得分:14)
致电filter
后,您需要将结果传递给map
,如下所示:
let filteredArray = arrayOfElements
.filter((element) =>
element.subElements.some((subElement) => subElement.surname === 1))
.map(element => {
let newElt = Object.assign({}, element); // copies element
return newElt.subElements.filter(subElement => subElement.surName === '1');
});
我在这里假设您不想操纵原始数组。所以,我正在使用Object.assign。
答案 1 :(得分:6)
let filteredArray = arrayOfElements
.filter((element) =>
element.subElements.some((subElement) => subElement.surname == 1))
.map(element => {
return Object.assign({}, element, {subElements : element.subElements.filter(subElement => subElement.surname == 1)});
});
答案 2 :(得分:4)
试试这个解决方案:
data_filter = arrayOfElements.filter(function (element) {
return element.subElements.some( function (subElement) {
return subElement.surname === surname
});
});
答案 3 :(得分:3)
只是改进了上面的答案
let elements =
[
{
"name": "a",
"subElements":
[
{"surname": 1},
{"surname": 2}
]
},
{
"name": "b",
"subElements":
[
{"surname": 3},
{"surname": 1}
]
},
{
"name": "c",
"subElements":
[
{"surname": 2},
{"surname": 5}
]
}
];
var value = 1;
var filteredArray = elements
.filter(element => element.subElements
.some(subElement => subElement.surname === value)
)
.map(element => {
let n = Object.assign({}, element, {'subElements': element.subElements.filter(
subElement => subElement.surname === value
)})
return n;
})
console.log(filteredArray)
答案 4 :(得分:2)
这样,您可以根据需要深入数组并在任何级别过滤元素,
arrayOfElements.map((element) => {
return {...element, subElements: element.subElements.filter((subElement) => subElement.surname === 1)}
})
Spread operator
将展开element
,然后将使用过滤后的值覆盖subElements
键。
答案 5 :(得分:1)
function display_message() {
let arrayOfElements = [{
"name": "a",
"subElements": [{
"surname": 1
}, {
"surname": 2
}]
}, {
"name": "b",
"subElements": [{
"surname": 3
}, {
"surname": 1
}]
}, {
"name": "c",
"subElements": [{
"surname": 2
}, {
"surname": 5
}]
}];
// console.log(arrayOfElements);
var surname = 1;
let filteredArray = arrayOfElements.filter((element) => element.subElements.some((subElement) => subElement.surname === surname));
for(var data in filteredArray){
filteredArray[data].subElements = {"surname": surname};
}
console.log(filteredArray);
}

<input type="button" onclick="display_message();" value="click"/>
&#13;
答案 6 :(得分:1)
您也可以将其设为通用:
subElements
值设置为已过滤列表。
let arrayOfElements=[{name:"a",subElements:[{surname:1},{surname:2}]},{name:"b",subElements:[{surname:3},{surname:1}]},{name:"c",subElements:[{surname:2},{surname:5}]}];
let distinct_surnames = [];
arrayOfElements.forEach(function(el) {
el.subElements.forEach(function(s) {
if (distinct_surnames.indexOf(s.surname) < 0) distinct_surnames.push(s.surname)
});
})
let result = [];
distinct_surnames.forEach(function(sn) {
let inter = [];
arrayOfElements.forEach(function(el) {
let f = el.subElements.filter(function(sub) {
return sub.surname === sn;
});
if (f.length > 0) {
let _tmp = Object.assign({}, el);
_tmp.subElements = f;
inter.push(_tmp);
}
});
result.push(inter);
})
console.log(result)
&#13;
注意:箭头功能用于保留this
的引用。如果你没有使用this
内部函数,你也可以使用普通函数。
答案 7 :(得分:0)
let filteredArray = arrayOfElements
.filter((element) =>
element.subElements.some((subElement) => subElement.surname === 1))
.map(element => {
let newElt = Object.assign({}, element); // copies element
newElt.subElements = newElt.subElements.filter(subElement => subElement.surName === '1');
return newElt;
});
更正确