samir
samir

Reputation: 25

filter object from array of object by given array

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);

Upvotes: 1

Views: 94

Answers (3)

PeterKA
PeterKA

Reputation: 24648

Before filtering as desired, you would have to map each element to elements that only include the desired tagIds as follows:

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": { } } ], } ],
    
    tagId = ['ABC','FRRRR'],
    
    r = data.map(
        ({serviceTags,...rest}) => ({rest,serviceTags:serviceTags.filter(
            ({tagId:tid}) => tagId.includes(tid)
        )})
    )
    .filter(d => d.serviceTags.every(c => tagId.includes(c.tagId)));


console.log(r);

Upvotes: 1

pilchard
pilchard

Reputation: 12956

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);

Upvotes: 0

Terry Lennox
Terry Lennox

Reputation: 30725

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; }

Upvotes: 0

Related Questions