Skip to content Skip to sidebar Skip to footer

How To Get Specific Properties Of Array Of Objects In JS?

I have the following code and test data: const getNestedObject = (nestedObj, pathArr) => { return pathArr.reduce((obj, key) => { return (obj && obj[key] !

Solution 1:

You can combine reduce() with map(). Basically reduce your main array into an flattened array of all the c.f items. This checks for the c property just in case the object doesn't have it:

const obj = [{a: 1,c: [{d: 1,e: 'string',f: [{value: 0,},{value: 1,}],},],},{a: 2,c: [{d: 2,e: 'string',f: [{value: 3,},{value: 4,}],},],},];

let Fs = obj.reduce((arr, item) => 
    item.c
    ? arr.concat(...item.c.map(itemc => itemc.f ))  // concat for flattened rather than nested arrays
    : arr
    , []);

console.log(Fs)

Solution 2:

Here's a fast iterative solution that won't overflow the stack, makes no assumptions about target result values being arrays (only spreads if they are) and doesn't hard-code child key names (it'll explore any values that are arrays).

This can also work if the target has children matching the key that you'd like to include in the search (swap else if with if).

const get = (data, target) => {
  const result = [];
  const stack = [data];
  
  while (stack.length) {
    const curr = stack.pop();
    
    for (const o of curr) {
      for (const k in o) {
        if (k === target) {
          if (Array.isArray(o[k])) {
            result.push(...o[k]);
          }
          else {
            result.push(o[k]);
          }
        }
        else if (Array.isArray(o[k])) {
          stack.push(o[k]);
        }
      }
    }
  }
  
  return result;
};
 
const obj = 
[
  {
      a: 1,
      c: [
        {
          d: 1,
          e: 'string',
          f: [
            {
              value: 0,
            },
            {
              value: 1,
            }
          ],
        },
      ],
  },
    {
      a: 2,
      c: [
        {
          d: 2,
          e: 'string',
          f: [
            {
              value: 3,
            },
            {
              value: 4,
            }
          ],
        },
      ],
  },
 ];
 
 console.log(get(obj, "f"));

Solution 3:

You can recursively traverse any objects and arrays to fetch a given property. This works at any depth and doesn't care about the structure of the objects:

const obj=[{a:1,c:[{d:1,e:"string",f:[{value:0},{value:1}]}]},{a:2,c:[{d:2,e:"string",f:[{value:3},{value:4}]}]}];

//curried function to grab a property by name off some object or array
function grab(prop) {
  //naming the inner function means it can be called recursively by name
  return function recursiveGrab(target) {
    if (Array.isArray(target)) {
      const arrayResult = target
          .filter(x => typeof x === "object") //remove non-objects (and non-arrays)
          .filter(Boolean) //remove null
          .map(recursiveGrab); //recursively call for the remaining objects 
      return flatten(arrayResult); //return a single dimensional array
    }
    
    //an object has the property - return it
    if (prop in target) {
      return target[prop];
    }
    
    //object doesn't have the property - check all values
    return recursiveGrab(Object.values(target));
  }
}

//small helper function. It's separated only to keep the logic for the traversal clear
function flatten(arr) {
  return arr.reduce((acc, curr) => acc.concat(curr), [])
}

const grabF = grab('f');

console.log(grabF(obj));

Solution 4:

I did not notice that f was always inside c. I have this recursive and dirty looking solution that works with f being inside any of the fields

        const objArray = [
          {
              a: 1,
              c: [
                {
                  d: 1,
                  e: 'string',
                  f: [
                    {
                      value: 0,
                    },
                    {
                      value: 1,
                    }
                  ],
                },
              ],
             d: [
                {
                  d: 1,
                  e: 'string',
                  f: [
                    {
                      value: 'd',
                    },
                    {
                      value: 'd1',
                    }
                  ],
                },
              ],
          },
            {
              a: 2,
              c: [
                {
                  d: 2,
                  e: 'string',
                  f: [
                    {
                      value: 3,
                    },
                    {
                      value: 4,
                    }
                  ],
                },
              ],
              e: [
                {
                  d: 1,
                  e: 'string',
                  f: [
                    {
                      value: 'e',
                    },
                    {
                      value: 'e1',
                    }
                  ],
                },
              ],
            }
        ]
         
         
         const getFObject = (obj) => {
           let fObj = [];
           Object.keys(obj).some(key => {
             if (key === 'f') {
               fObj = obj[key];
               return true;
             }
             if (Array.isArray(obj[key])) {
               obj[key].forEach(nestedObj => {
                 fObj = fObj.concat(getFObject(nestedObj))
               });
             }
             return false;
           });
           return fObj;
         }
         
         const newArray = objArray.reduce((acc, obj) => {
           return acc.concat(getFObject(obj))
         }, []);
         console.log(newArray)

Post a Comment for "How To Get Specific Properties Of Array Of Objects In JS?"