如何从Lodash的嵌套对象集合中获取一系列图像?

时间:2015-07-13 10:00:51

标签: json lodash

 {
     "shop": {
         "homebackground": "http://padmenu.s3.amazonaws.com/15/11/2014/05/08/2ec2ff61-d6a0-11e3-8857-10ddb1e6e201.jpg",
         "name": {
             "tr": "My Shop"
         },
         "menus": [{
                 "name": {
                     "en": "Menu"
                 },
                 "children": [{
                     "name": {
                         "en_US": "Category"
                     },
                     "images": [
                         "http://www.progressivedental-ellenlimdds.com/wp-content/uploads/2014/06/red-wine.jpg"
                     ],
                     "children": [{
                         "name": {
                             "en_US": "Item"
                         },
                         "images": [
                             "http://res.cloudinary.com/finedine/image/upload/c_fill,g_center,h_600/v1435916818/WIne-Bottle_uz03a0.jpg",
                             "http://media.riepenau.com/wines/17973_b.jpg",
                             "http://lorempixel.com/400/400/food/3",
                             "http://lorempixel.com/400/400/food/4",
                             "http://lorempixel.com/400/400/food/5",
                             "http://lorempixel.com/400/400/food/6",
                             "http://lorempixel.com/400/400/food/7"
                         ]
                     }]
                 }]
             }]
         }
     }

我想从商店的“儿童”对象中选择所有“图像”数组。 我怎么能用Lodash库来做到这一点? 输出应该是由图像URL组成的数组: [ “URL1”, “URL2”, “URL3”]

3 个答案:

答案 0 :(得分:2)

解决这个问题的最简单方法是递归地追捕孩子及其后代。重点在于getImages()功能;其中它在一个级别中展平所有子阵列,拔出每个图像阵列并压缩所有项目以移除未定义的值(由没有图像的孩子引起),然后展平图像阵列并准备连接。递归的停止点是当前children没有图像时,返回一个空数组。如果找到图像,那么我们递归地连接所有潜在的后代图像。至于我们如何获得后代,我们使用与获取images数组但使用children作为采集键时使用的相同链接序列。

<强> DEMO

function getImages(children) {
  var images = _(children).flatten().pluck('images').compact().flatten().value();
  if(_.isEmpty(images)) {
    return [];
  }
  var descendants = _(children).flatten().pluck('children').compact().flatten().value();
  return images.concat(getImages(descendants));
}

function getShopImages(data) {
  var children = _.pluck(data.shop.menus, 'children');
  return getImages(children);
}

console.log(getShopImages(data));

答案 1 :(得分:1)

伪代码

你可以通过一点点递归来解决这个问题:

  1. 抓住孩子名单。
  2. 使用pluck从儿童列表中提取所有图片。
  3. 对所有后代重复步骤1。
  4. Concat所有结果并展平。
  5. 核心代码

    function deepExtract(collection, childKey, property) {
      var exists = _.negate(_.isEmpty);
      var children = _.chain(collection).pluck(childKey).filter(exists).flatten();
    
      if (_.isEmpty(children.value())) {
        return [];
      }
    
      var images = children.pluck(property).value();
      var descendantImages = deepExtract(children.value(), childKey, property);
    
      return _.flatten(images.concat(descendantImages));
    };
    
    var tree = _.chain(data).get('shop.menus').value();
    
    var images = deepExtract(tree, 'children', 'images');
    

    演示

    &#13;
    &#13;
    var data = {
      "shop": {
        "homebackground": "http://padmenu.s3.amazonaws.com/15/11/2014/05/08/2ec2ff61-d6a0-11e3-8857-10ddb1e6e201.jpg",
        "name": {
          "tr": "My Shop"
        },
        "menus": [{
          "name": {
            "en": "Menu"
          },
          "children": [{
            "name": {
              "en_US": "Category"
            },
            "images": [
              "http://www.progressivedental-ellenlimdds.com/wp-content/uploads/2014/06/red-wine.jpg"
            ],
            "children": [{
              "name": {
                "en_US": "Item"
              },
              "images": [
                "http://res.cloudinary.com/finedine/image/upload/c_fill,g_center,h_600/v1435916818/WIne-Bottle_uz03a0.jpg",
                "http://media.riepenau.com/wines/17973_b.jpg",
                "http://lorempixel.com/400/400/food/3",
                "http://lorempixel.com/400/400/food/4",
                "http://lorempixel.com/400/400/food/5",
                "http://lorempixel.com/400/400/food/6",
                "http://lorempixel.com/400/400/food/7"
              ]
            }]
          }]
        }]
      }
    };
    
    function deepExtract(collection, childKey, property) {
      var exists = _.negate(_.isEmpty);
      var children = _.chain(collection).pluck(childKey).filter(exists).flatten();
    
      if (_.isEmpty(children.value())) {
        return [];
      }
    
      var images = children.pluck(property).value();
      var descendantImages = deepExtract(children.value(), childKey, property);
    
      return _.flatten(images.concat(descendantImages));
    };
    
    var tree = _.chain(data).get('shop.menus').value();
    log(deepExtract(tree, 'children', 'images'));
    
    
    // Helper method to output to screen
    function log(value) {
        document.getElementById("output").innerHTML += JSON.stringify(value, null, 2) + "\n"
    }
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
    <pre id="output"></pre>
    &#13;
    &#13;
    &#13;

答案 2 :(得分:1)

我在这里找到了另一种解决方案:

  var children = _(shop.menus[0].children)
    .thru(function(coll) {
        return _.union(coll, _.pluck(coll, 'children'));
    })
    .flatten();

var images = _.chain(children).pluck('images').flattenDeep().compact().uniq().value();

输出&#34;图像&#34;是一个图像数组。