简体   繁体   中英

Get Object when the array contains the input value inside nested Array of objects

Here is the nested array of object i am working on:

let arrayOfElements = 
[
    {
       "username": "a",
       "attributes": 
       {
         roles:["Tenant-Hyd"],
         groups:["InspectorIP", "InspectorFT"]
       }
    },
    {
       "username": "b",
       "attributes": 
       {
         roles:["Tenant-Pune"],
      groups:["InspectorIP"]
       }
    },
    {
       "username": "c",
       "attributes": 
       {
         roles:["Tenant-Hyd"],
      groups:["InspectorIP"]
       }
    }
];

I want users if they have Tenant-hyd role and also if groups has more then one string, then the user should be spit two. so the final output should be:

arrayOfElements=[
{
    "username": "a",
     groups:"InspectorIP"
   },
   {
    "username": "a",
     groups:"InspectorFT"
   },
{
   "username": "c",

  groups:"InspectorIP"

}
];

You can use the following snippet

 let arrayOfElements = [{ "username": "a", "attributes": { roles: ["Tenant-Hyd"], groups: ["InspectorIP", "InspectorFT"] } }, { "username": "b", "attributes": { roles: ["Tenant-Pune"], groups: ["InspectorIP"] } }, { "username": "c", "attributes": { roles: ["Tenant-Hyd"], groups: ["InspectorIP"] } } ]; var newa = []; for (var i in arrayOfElements) { if (arrayOfElements[i].attributes.roles[0] === 'Tenant-Hyd') { for (var j in arrayOfElements[i].attributes.groups) { var newObj = { 'username': arrayOfElements[i].username, 'groups': arrayOfElements[i].attributes.groups[j] }; newa.push(newObj); } } } console.log(newa);

You can try this code

 let arrayOfElements = [{ "username": "a", "attributes": { roles: ["Tenant-Hyd"], groups: ["InspectorIP", "InspectorFT"] } }, { "username": "b", "attributes": { roles: ["Tenant-Pune"], groups: ["InspectorIP"] } }, { "username": "c", "attributes": { roles: ["Tenant-Hyd"], groups: ["InspectorIP"] } } ]; var res = []; arrayOfElements.forEach(d => { if (d.attributes.roles[0] == "Tenant-Hyd") { d.attributes.groups.forEach(x => { res.push({ "username": d.username, "groups": x }) }) } }); console.log(res);

I would use a combination of filter and reduce array functions here.

filter would remove all elements where attributes.roles does not include 'Tenant-Hyd' .

reduce would then flatten the groups array.

 const arrayOfElements = [ { "username": "a", "attributes": { roles:["Tenant-Hyd"], groups:["InspectorIP", "InspectorFT"] } }, { "username": "b", "attributes": { roles:["Tenant-Pune"], groups:["InspectorIP"] } }, { "username": "c", "attributes": { roles:["Tenant-Hyd"], groups:["InspectorIP"] } } ]; const filtered = arrayOfElements.filter(x => x.attributes.roles.includes('Tenant-Hyd')); console.log('filtered', filtered); const flattened = filtered.reduce((arr, current) => { // create a new object for each group with the current username const groups = current.attributes.groups.map(group => ({ username: current.username, groups: group })); // push the new objects into the array arr.push(...groups); // return the array to the next iteration return arr; }, []); console.log('flattened', flattened);

This demo sets up the initial array, runs the filter , and then runs the reduce . I have separated the steps out so you can see what's going on at each stage, but you could easily combine them.

const result = arrayOfElements
  .filter(x => x.attributes.roles.includes('Tenant-Hyd'))
  .reduce((arr, current) => {
    arr.push(...current.attributes.groups.map(group => ({
      username: current.username,
      groups: group
    })));
    return arr;
  }, []);

The reduce function

The reduce array function accepts a callback and an initial value. I am passing an empty array in as the initial value.

It is really a more powerful map . The source array will be iterated over, with the callback being called on each iteration. The value returned from the callback will be used as the accumulator on the next iteration.

// declare the callback
const callback = (arr, current) => {
  // arr is the initial value on the first loop
  // and whatever we return from this callback on subsequent loops

  // add our flattened items to the accumulated array
  arr.push(...current.attributes.groups.map(group => ({
    username: current.username,
    groups: group
  })));

  // return the accumulated array to the next iteration
  return arr;
};

// loop over the items in myArray, calling the callback for each item
// pass an empty array in as the accumulator
myArray.reduce(callback, []);

A simpler alternative would be this:

const arr = [];
myArray.forEach(current => {
  arr.push(...current.attributes.groups.map(group => ({
    username: current.username,
    groups: group
  })));
});

This is easier to understand, but is not as concise as using reduce .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM