alfrescian
alfrescian

Reputation: 4079

reduce an object-structure to only contain values of specific properties

Assume sth like the following object given:

const foo = {
  id: 'foo',
  name: '...',
  test: () => 'fn',
  nestedObject: {
    id: 'nested',
    name: '...',
    nestedObjects: [{
      id: 'bar',
      name: '...',
      anotherNested: {
        id: 'n1',
        name: '...',
        oneMoreNestedObjects: [{
          id: 'n11',
          name: '...',
        }, {
          id: 'n12',
          name: '...',
        }]
      }
    }, {
      id: 'bar2',
      name: '...',
    }]
  }
};

I would like to transform that into an object by only picking properties with name id or if it's an (Array of) Object(s) that has an id property. So in my example it would be:

const result = {
  id: 'foo',
  nestedObject: {
    id: 'nested',
    nestedObjects: [{
      id: 'bar',
      anotherNested: {
        id: 'n1',
        oneMoreNestedObjects: [{
          id: 'n11',
        }, {
          id: 'n12',
        }]
      }
    }, {
      id: 'bar2',
    }]
  }
};

btw: I'm fine with using lodash.

Upvotes: 1

Views: 109

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386756

You could use an iterative an recursive approach for nested arrays and objects.

function filter(object) {
    return Object.keys(object).reduce(function (r, k) {
        if (k === 'id') {
            r[k] = object[k];
        } else if (object[k] && typeof object[k] === 'object') {
            r[k] = filter(object[k]);
        }
        return r;
    }, Array.isArray(object) ? [] : {});
}

var foo = { id: 'foo', name: '...', test: () => 'fn', nestedObject: { id: 'nested', name: '...', nestedObjects: [{ id: 'bar', name: '...', anotherNested: { id: 'n1', name: '...', oneMoreNestedObjects: [{ id: 'n11', name: '...', }, { id: 'n12', name: '...', }] } }, { id: 'bar2', name: '...', }] } },
    result = filter(foo);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Benji Lees
Benji Lees

Reputation: 815

Have you thought about using recursion? be aware with deep objects this can exceed the maximum call stack.

  function getIdsFromObjects(nObj) {
    return Object.keys(nObj).reduce(function (curr, next) {
      if (next === 'id') {
        curr[next] = nObj[next]
      }
      if (Array.isArray(nObj[next])) {
        curr[next] = nObj[next].map(function(mapObj) {
          return getIdsFromObjects(mapObj)
        })
      }
      if (typeof obj[next] === 'object' && !Array.isArray(nObj[next])) {
         curr[next] = getIdsFromObjects(nObj[next])
      }
      return curr;
    },{})
  }

console.log(JSON.stringify(getIdsFromObjects(foo), null, 4))

Upvotes: 0

Related Questions