lodash pick in nested array

11,642

Create an object with the url property and the value of sizes.thumbnail.url using _.get(), and combine it with to the results of the _.pick().

Note: I've used object spread to merge the results, but you can use Object.assign() or lodash's equivalent instead.

const images = [{"sizes":{"thumbnail":{"height":300,"width":300,"url":"http://example.com/wp-content/uploads/2017/04/web-300x300.jpg","orientation":"landscape"},"medium":{"height":267,"width":400,"url":"http://example.com/wp-content/uploads/2017/04/web-400x267.jpg","orientation":"landscape"},"large":{"height":441,"width":660,"url":"http://example.com/wp-content/uploads/2017/04/web-1024x684.jpg","orientation":"landscape"},"full":{"url":"http://example.com/wp-content/uploads/2017/04/web.jpg","height":1200,"width":1796,"orientation":"landscape"}},"mime":"image/jpeg","type":"image","subtype":"jpeg","id":3589,"url":"http://example.com/wp-content/uploads/2017/04/web.jpg","alt":"","link":"http://example.com/web/","caption":""}];

const result = images.map((image) => ({
  ..._.pick(image, ['alt', 'caption', 'id']),
  url: _.get(image, 'sizes.thumbnail.url')
}));

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

A more generic solution would a function that accepts a list of paths, and generate an array of pairs [last part of path, value]. The function converts the pairs to an object using _.fromPairs() (or Object.fromEntries()):

const deepPick = (paths, obj) => 
  _.fromPairs(paths.map(p => [
    _.last(p.split('.')),
    _.get(obj, p),
  ]))

const images = [{"sizes":{"thumbnail":{"height":300,"width":300,"url":"http://example.com/wp-content/uploads/2017/04/web-300x300.jpg","orientation":"landscape"},"medium":{"height":267,"width":400,"url":"http://example.com/wp-content/uploads/2017/04/web-400x267.jpg","orientation":"landscape"},"large":{"height":441,"width":660,"url":"http://example.com/wp-content/uploads/2017/04/web-1024x684.jpg","orientation":"landscape"},"full":{"url":"http://example.com/wp-content/uploads/2017/04/web.jpg","height":1200,"width":1796,"orientation":"landscape"}},"mime":"image/jpeg","type":"image","subtype":"jpeg","id":3589,"url":"http://example.com/wp-content/uploads/2017/04/web.jpg","alt":"","link":"http://example.com/web/","caption":""}];

const result = images.map(image => deepPick(
  ['alt', 'caption', 'id', 'sizes.thumbnail.url'], 
  image
));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Share:
11,642
leemon
Author by

leemon

Updated on June 14, 2022

Comments

  • leemon
    leemon almost 2 years

    I have an array of objects like this:

    {
      "sizes":{
         "thumbnail":{
            "height":300,
            "width":300,
            "url":"http://example.com/wp-content/uploads/2017/04/web-300x300.jpg",
            "orientation":"landscape"
         },
         "medium":{
            "height":267,
            "width":400,
            "url":"http://example.com/wp-content/uploads/2017/04/web-400x267.jpg",
            "orientation":"landscape"
         },
         "large":{
            "height":441,
            "width":660,
            "url":"http://example.com/wp-content/uploads/2017/04/web-1024x684.jpg",
            "orientation":"landscape"
         },
         "full":{
            "url":"http://example.com/wp-content/uploads/2017/04/web.jpg",
            "height":1200,
            "width":1796,
            "orientation":"landscape"
         }
      },
      "mime":"image/jpeg",
      "type":"image",
      "subtype":"jpeg",
      "id":3589,
      "url":"http://example.com/wp-content/uploads/2017/04/web.jpg",
      "alt":"",
      "link":"http://example.com/web/",
      "caption":""
    }
    

    I'm using the following snippet to create a new array with just the alt, caption, id and url keys in the array:

    images.map( ( image ) => pick( image, [ 'alt', 'caption', 'id', 'url' ] ) ),
    

    My question is, how can I pick the sizes.thumbnail.url key instead of the root url key? Is it possible? If so, how?

    Thanks in advance

  • triple
    triple over 4 years
    This I think is a very verbose example that includes way more surface area for bugs. Use a Lodash or underscore option would be preferred in most any case
  • Raghav Sharma
    Raghav Sharma almost 4 years
    You deserve a medal for this!
  • user2495085
    user2495085 almost 2 years
    "plain js" is usually called "VanillaJs".
  • IlyaEremin
    IlyaEremin almost 2 years
    deep pick... sorry makes me laugh haha