Nikita Iskorkin
Nikita Iskorkin

Reputation: 13

How to deep pick in another pick with lodash?

Now i have code like this:

var object = {
   a: 'a',
   b: 'b',
   c: {
       d: 'd'
   }
}
_.get(object).pick(['a', 'b']).value();

How to deep pick property 'd' like:

_.get(object).pick(['a', 'b', 'c.d']).value();

Upvotes: 0

Views: 4614

Answers (5)

samarjit samanta
samarjit samanta

Reputation: 1315

I am not very clear from your question if you want just the values to be extracted destructuring might be an option. But if you just want to pick specific properties eg. 'd', and keep the original json structure as it is, then there is a trick.

JSON.stringify(object, ['c','d'], 0)

Result:

'{"c":{"d":"d"}}'

Good thing is it works for array or objects.

x = {
 top1: 1, 
 top2: {
    level2: [
        { leaf1a: 'a', leaf1b: 'b'},
        {leaf2a:'2a', leaf2b: '2b'}
    ]
 }
}

With JSON.stringify(x, ['level2','top2', 'leaf2a'], 0)

Will result in below structure.

{
 "top2": {
  "level2": [
   {},
   {
    "leaf2a": "2a"
   },
   {}
  ]
 }
}

Its not perfect as you can see empty child elements, I only use this for analyzing deep nested structure with lots of attributes at each level, even used it sometimes for logging necessary items in a program.

Upvotes: 0

Guy
Guy

Reputation: 13296

This can work for lodash:

function pickNested(object: Json, fields: string[]) {
    const shallowFields = fields.filter((field) => !field.includes('.'));
    const deepFields = fields.filter((field) => field.includes('.'));

    const initialValue = _.pick(object, shallowFields) as Json;

    return deepFields.reduce((output, field) => {
        const key = _.snakeCase(field);
        output[key] = _.get(object, field);
        return output;
    }, initialValue);
}

and:

const json = {
    id: '10',
    user: {
        email: '[email protected]',
    },
};

const newData = pickNested(json, ['id', 'user.email']);
console.log('newData ->', newData);
/*
{
    id: '10',
    user_email: '[email protected]',
};
*/

Upvotes: 0

amedina
amedina

Reputation: 3426

In case you insist in using Lodash, consider using the _.get() function:

_.get(object, 'c.d');

So, for the properties you want to get:

const selectedProps = {
  ..._.pick(object, ['a', 'b']),
  _.get(object, 'c.d')
}

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191976

You can create a flatPick() function. The function iterates the array of paths. and uses _.get() to get the value of the path, and _.set() to add the last part of the path as property on the result object:

function flatPick(object, paths) {
  const o = {};

  paths.forEach(path => _.set(
    o,
    _.last(path.split('.')),
    _.get(object, path)
  ));

  return o;
}

var object = {
  a: 'a',
  b: 'b',
  c: {
    d: 'd',
    e: {
      f: 'f'
    }
  }
};

var result = flatPick(object, ['a', 'b', 'c.d', 'c.e.f']);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Upvotes: 1

Taki
Taki

Reputation: 17654

you can deep destructure without lodash :

var object = {
  a: 'a',
  b: 'b',
  c: {
      d: 'd'
  }
}

const { a, b, c :{ d }} = object;

console.log(a,b,d);

const obj = {a, b, d};

console.log(obj);

Upvotes: 4

Related Questions