简体   繁体   中英

lodash pick in nested array

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

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>

 var array = [{"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":""}]; var result = _.map(array, v => ({"alt":v.alt, "caption":v.caption, "id":v.id, "url":v.sizes.thumbnail.url})); console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

You can use plain js,

 function pickfromobject(object, key){ var parts= key.split('.') if(parts.length > 1){ var tempkey = parts.shift() if(!object[tempkey]){ return null } else{ return pickfromobject(object[tempkey], parts.join('.')) } } else{ return object[parts[0]] } } function pick(arr, key){ var result = [] for(var i =0;i<arr.length; i++){ result.push({[key]: pickfromobject(arr[i], key)}) } return result } var a = [{a: {c:{d:1}}, b:2}, {a:{c:{d:3}}, b:3}] console.log(pick(a, 'acd'))

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