[英]Nested filtering of array in Javascript
I have two arrays:我有两个 arrays:
countriesArr
: countriesArr
:
[
{
"countryCode": "DEU",
"name": "Germany",
"companyFunctions": [
{
"name": "E-Commerce",
"companyName": "Company 1"
}
]
},
{
"countryCode": "FRA",
"name": "France",
"companyFunctions": [
{
"name": "Shopping Centre",
"companyName": "Company 1"
},
{
"name": "Support Services",
"companyName": "Company 2"
},
{
"name": "Procurement Support",
"companyName": "Company 3"
},
{
"name": "Retail",
"companyName": "Company 3"
}
]
}
]
and filterArr
:和filterArr
:
[
{
"name": "Company 2",
"id": "32434d324-32434"
},
{
"name": "Company 3",
"id": "2643d3254-39244"
}
]
What I want to do is filter the countriesArr
by looping through the countriesArr
array where countriesArr.companyFunctions.companyName === filterArr.name
.我想要做的是通过countriesArr
Arr 数组中的countriesArr.companyFunctions.companyName === filterArr.name
循环过滤countriesArr
Arr。
I wrote the following code:我写了以下代码:
countriesArr.filter(p =>
p.companyFunctions.filter(cF =>
filterArr.filter(c => c.name === cF.companyName)
)
);
But this doesn't seem to work as it returns also the German object from countriesArr
and it includes Company 1
in the companyFunctions
of the French object from countriesArr
while Company 1
isn't in the filterArr
.但这似乎不起作用,因为它还返回了来自countriesArr
的德国 object 并且它在companyFunctions
中包含来自countriesArr
的法国 object 的Company 1
1 而Company 1
不在filterArr
中。
What am I doing wrong?我究竟做错了什么?
The desired result should look like:所需的结果应如下所示:
[
{
"countryCode": "FRA",
"name": "France",
"companyFunctions": [
{
"name": "Support Services",
"companyName": "Company 2"
},
{
"name": "Procurement Support",
"companyName": "Company 3"
},
{
"name": "Retail",
"companyName": "Company 3"
}
]
}
]
const countriesArr = [ { countryCode: 'DEU', name: 'Germany', companyFunctions: [ { name: 'E-Commerce', companyName: 'Company 1', }, ], }, { countryCode: 'FRA', name: 'France', companyFunctions: [ { name: 'Shopping Centre', companyName: 'Company 1', }, { name: 'Support Services', companyName: 'Company 2', }, { name: 'Procurement Support', companyName: 'Company 3', }, { name: 'Retail', companyName: 'Company 3', }, ], }, ]; const filterArr = [ { name: 'Company 2', id: '32434d324-32434', }, { name: 'Company 3', id: '2643d3254-39244', }, ].map((f) => f.name); const result = countriesArr.map((c) => ({...c, companyFunctions: c.companyFunctions.filter((cf) => filterArr.includes(cf.companyName)), })).filter((c) => c.companyFunctions.length > 0); console.log(result);
You could rebuild a new object if companyFunctions
contains the wanted names.如果companyFunctions
包含所需的名称,您可以重建一个新的 object。
This approach take a hash table for wanted names
where the property is true
.这种方法采用 hash 表来获取属性为true
的所需names
。 This allows to filter later just with the destructured property companyName
and a simple call of the property of names
.这允许稍后仅使用解构属性companyName
和简单调用names
的属性进行过滤。
Finally, if the filteres array has a truthy (any other value except zero) length, take this array along with the rest of the object and pus a new object to the result set.最后,如果过滤器数组的长度为真(除零以外的任何其他值),则将此数组与 object 的 rest 一起放入结果集中。
const countriesArr = [{ countryCode: "DEU", name: "Germany", companyFunctions: [{ name: "E-Commerce", companyName: "Company 1" }] }, { countryCode: "FRA", name: "France", companyFunctions: [{ name: "Shopping Centre", companyName: "Company 1" }, { name: "Support Services", companyName: "Company 2" }, { name: "Procurement Support", companyName: "Company 3" }, { name: "Retail", companyName: "Company 3" }] }], filterArr = [{ name: "Company 2", id: "32434d324-32434" }, { name: "Company 3", id: "2643d3254-39244" }], names = filterArr.reduce((r, { name }) => (r[name] = true, r), {}), result = countriesArr.reduce((r, { companyFunctions, ...o }) => { companyFunctions = companyFunctions.filter(({ companyName }) => names[companyName]); if (companyFunctions.length) r.push({...o, companyFunctions }); return r; }, []); console.log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
What you want is not a filter over countriesArr
but a map() (to transform it) and then a filter() (to remove entries with 0 companyFunctions) or vice-versa (first filter() those having at least one matching companyFunction
and then map to transform removing unwanted ones).您想要的不是对countriesArr
的过滤器,而是map() (转换它)然后是filter() (删除具有 0 companyFunctions 的条目)或反之亦然(第一个filter()具有至少一个匹配companyFunction
和然后 map 转换删除不需要的)。 But mapping and then filtering seems more straightforward to me...但是映射然后过滤对我来说似乎更直接......
const result = countriesArr
.map(function(ca) {
ca.companyFunctions = ca.companyFunctions.filter(
cf => filterArr.some(fa=>fa.name==cf.companyName)
);
return ca;
})
.filter(ca=>ca.companyFunctions.length)
;
console.log(JSON.stringify(result, null, 4));
// [
// {
// "countryCode": "FRA",
// "name": "France",
// "companyFunctions": [
// {
// "name": "Support Services",
// "companyName": "Company 2"
// },
// {
// "name": "Procurement Support",
// "companyName": "Company 3"
// },
// {
// "name": "Retail",
// "companyName": "Company 3"
// }
// ]
// }
// ]
var countriesArr = [{ "countryCode": "DEU", "name": "Germany", "companyFunctions": [{ "name": "E-Commerce", "companyName": "Company 1" }] }, { "countryCode": "FRA", "name": "France", "companyFunctions": [{ "name": "Shopping Centre", "companyName": "Company 1" }, { "name": "Support Services", "companyName": "Company 2" }, { "name": "Procurement Support", "companyName": "Company 3" }, { "name": "Retail", "companyName": "Company 3" } ] } ]; var filterArr = [{ "name": "Company 2", "id": "32434d324-32434" }, { "name": "Company 3", "id": "2643d3254-39244" } ] console.log(countriesArr.filter(item => { return filterArr.findIndex(company => item.companyFunctions.some(d => d.companyName === company.name)) != -1 }))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.