I have an array of JSON like below
const data = [
{
"uniqueId": 1233,
"serviceTags": [
{
"Id": 11602,
"tagId": "FRRRR",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
}
],
},
{
"uniqueId": 34555,
"serviceTags": [
{
"Id": 11602,
"tagId": "JWJN2",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
}
],
},
{
"uniqueId": 44422,
"serviceTags": [
{
"Id": 11602,
"tagId": "ABC",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
},
{
"Id": 11602,
"tagId": "BBC",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
}
],
}
]
I want to filter array of object by below tagId
const tagId = ['ABC','FRRRR'];
filter array of json should be like
[
{
"uniqueId": 1233,
"serviceTags": [
{
"Id": 11602,
"tagId": "FRRRR",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
}
],
},
{
"uniqueId": 44422,
"serviceTags": [
{
"Id": 11602,
"tagId": "ABC",
"missingRequired": [
],
"summaries": [
{
"contract": "ACTIVE",
},
{
"contract": "INACTIVE",
}
],
"lttributes": {
}
}
],
}
]
try to do by below way but I am not able to get exact output
const r = data.filter(d => d.serviceTags.every(c => tagId.includes(c.tagId)));
console.log(r);
CodePudding user response:
You can use Array.reduce()
to get the result in the desired form.
For each item in the data
array, we check if any service tags match, using Array.filter().
If we get any matches we add the item to the result.
const data = [ { "uniqueId": 1233, "serviceTags": [ { "Id": 11602, "tagId": "FRRRR", "missingRequired": [ ], "summaries": [ { "contract": "ACTIVE", }, { "contract": "INACTIVE", } ], "lttributes": { } } ], }, { "uniqueId": 34555, "serviceTags": [ { "Id": 11602, "tagId": "JWJN2", "missingRequired": [ ], "summaries": [ { "contract": "ACTIVE", }, { "contract": "INACTIVE", } ], "lttributes": { } } ], }, { "uniqueId": 44422, "serviceTags": [ { "Id": 11602, "tagId": "ABC", "missingRequired": [ ], "summaries": [ { "contract": "ACTIVE", }, { "contract": "INACTIVE", } ], "lttributes": { } }, { "Id": 11602, "tagId": "BBC", "missingRequired": [ ], "summaries": [ { "contract": "ACTIVE", }, { "contract": "INACTIVE", } ], "lttributes": { } } ], } ]
const tagId = ['ABC','FRRRR'];
const result = data.reduce((acc, { serviceTags, ...item}) => {
const matchingTags = serviceTags.filter(st => tagId.includes(st.tagId));
if (matchingTags.length) {
acc.push({
...item,
serviceTags: matchingTags
})
}
return acc;
}, []);
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
CodePudding user response:
An alternate to the reduce()
option is to map()
the data with a nested filter on the serviceTags
and then filter()
the result to remove those entries with empty arrays.
const data = [{ uniqueId: 1233, serviceTags: [{ Id: 11602, tagId: 'FRRRR', missingRequired: [], summaries: [{ contract: 'ACTIVE', }, { contract: 'INACTIVE', },], lttributes: {}, },], }, { uniqueId: 34555, serviceTags: [{ Id: 11602, tagId: 'JWJN2', missingRequired: [], summaries: [{ contract: 'ACTIVE', }, { contract: 'INACTIVE', },], lttributes: {}, },], }, { uniqueId: 44422, serviceTags: [{ Id: 11602, tagId: 'ABC', missingRequired: [], summaries: [{ contract: 'ACTIVE', }, { contract: 'INACTIVE', },], lttributes: {}, }, { Id: 11602, tagId: 'BBC', missingRequired: [], summaries: [{ contract: 'ACTIVE', }, { contract: 'INACTIVE', },], lttributes: {}, },], },];
const tagId = ['ABC', 'FRRRR'];
const r = data
.map((d) => ({
...d,
serviceTags: d.serviceTags.filter((c) => tagId.includes(c.tagId)),
}))
.filter((d) => d.serviceTags.length);
console.log(r);