Underscorejs过滤深度对象2级别的集合

时间:2014-03-11 19:47:28

标签: javascript underscore.js

我有一个对象数组,包含对象数组,包含一个对象数组。

我想要做的是过滤最后一个对象数组中的属性。

这是一个示例数据集

    var sampleData=[
   {
      "name":"Cooking",
      "shelve":[
         {
            "name":"Shelve 1",
            "drawers":[
               {                  
                  "Name":"Left"
               },
               {
                  "Name":"Middle"
               }
            ]
         },
         {
            "name":"Shelve 2",
            "drawers":[
               {
                  "Name":"Middle side"
               },
               {
                  "Name":"Left"
               },
               {
                  "Name":"Up"
               }
            ]
         }
      ]
   },
   {
      "name":"DBs",
      "shelves":[
         {
            "name":"Shelve 3",
            "drawers":[
               {
                  "Name":"asdfasdf"
               },
               {
                  "Name":"New Test 12"
               }
            ]
         }
      ]
   }
];

基本上我想要做的是能够取回drawer.name包含子字符串的对象。我想让它返回完整的对象图,所以如果我搜索中,我会期望回来

var sampleData=[
   {
      "name":"Cooking",
      "shelve":[
         {
            "name":"Shelve 1",
            "drawers":[
               {
                  "Name":"Middle"
               }
            ]
         },
         {
            "name":"Shelve 2",
            "drawers":[
               {
                  "Name":"Middle side"
               }
            ]
         }
      ]
   }
];

我希望使用下划线会有所帮助,而我最初只是尝试嵌套过滤器,但这不起作用。

我尝试了以下内容,虽然发现它会评估为真,但它应该不会像我希望的那样过滤。

var secs = _.filter(sampleData, function(section) {
                _.filter(section.shelve, function(shelve) {
                    _.filter(shelve.drawers, function(drawer) {
                        var found = drawer.Name.indexOf('Middle') !== -1;
                        if(found) {
                            var xa = 'found it!!';
                        }
                        return drawer.Name.indexOf('Middle') !== -1;
                    });
                }); 
            });

这是一个快速的jsfiddler示例。 http://jsfiddle.net/cnalk/GtfNj/3/

1 个答案:

答案 0 :(得分:2)

不幸的是,像_.filter这样的基本数组过滤器并没有提供一种执行两步过滤的方法(首先,通过数组的值;然后通过传递了多少个值),所以你需要为每个层编写自己的过滤函数,例如:

function filter_shelf( shelf ) {

    var filtered = _.omit( shelf, 'drawers' );

    filtered.drawers = _.filter( shelf.drawers, filter_drawer );

    return filtered.drawers.length && filtered;

}

完整小提琴:http://jsfiddle.net/GtfNj/5/

每个步骤都会考虑过滤所需的属性,通过以下步骤"过滤"然后,如果属性从过滤器中清空,则返回自身的过滤副本或false。上面的步骤""然后根据该结果进行过滤。等等...

聚苯乙烯。您的示例数据使用shelveshelves不一致。