Underscore.js findWhere嵌套对象

wes*_*bos 10 javascript underscore.js lodash

我有一个文件夹/文件的对象,如下所示:

{
  about.html : {
    path : './about.html'
  },
  about2.html : {
    path : './about2.html'
  },
  about3.html : {
    path : './about3.html'
  },
  folderName : {
    path : './folderName',
    children : {
      sub-child.html : {
        path : 'folderName/sub-child.html'
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并且它可以在有孩子的文件夹的6-7级深度.

我想找到路径等于我提供的字符串的对象.无论它有多深.

我使用只有顶级的下划线:

_.findWhere(files,{path:'./about2.html'}
Run Code Online (Sandbox Code Playgroud)

如何进行深度嵌套搜索.下划线是否具有此功能,或者我是否需要使用递归构建mixin?

dar*_*ins 11

这不是最漂亮的代码,但我测试了它,它似乎按照你要求的方式工作.它设置为lodash/underscore mixin,但可以使用.用法如下:

_.findDeep(testItem, { 'path': 'folderName/sub-child.html' })
Run Code Online (Sandbox Code Playgroud)

执行:

findDeep: function(items, attrs) {

  function match(value) {
    for (var key in attrs) {
      if(!_.isUndefined(value)) {
        if (attrs[key] !== value[key]) {
          return false;
        }
      }
    }

    return true;
  }

  function traverse(value) {
    var result;

    _.forEach(value, function (val) {
      if (match(val)) {
        result = val;
        return false;
      }

      if (_.isObject(val) || _.isArray(val)) {
        result = traverse(val);
      }

      if (result) {
        return false;
      }
    });

    return result;
  }

  return traverse(items);

}
Run Code Online (Sandbox Code Playgroud)


McG*_*gle 9

而不是findWhere使用filter,它将函数作为谓词而不是键值映射.使用递归函数检查当前节点和可能的子节点.像这样的东西:

var searchText = './about2.html';

var recursiveFilter = function(x) {
    return x.path == searchText || 
        ( typeof x.children != 'undefined' && recursiveFilter(x.children['sub-child.html']) );
};

_.filter(files, recursiveFilter);
Run Code Online (Sandbox Code Playgroud)

编辑

假设这有效,你可能想要创建一个函数getRecursiveFilter(searchText).这是看起来如何:

function getRecursiveFilter(searchText) { 
    var recursiveFilter = function(x) {
        return x.path == searchText || 
            (typeof x.children != 'undefined' 
                && arguments.callee(x.children['sub-child.html']) );
    };
    return  recursiveFilter;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这里recursiveFilter用于arguments.callee递归调用自身.


这是一个有效的演示.


abe*_*rob 5

这已经有了一个公认的答案,但另一个答案非常干净,非常适合我的类似情况:https ://stackoverflow.com/a/21600748/1913975_.filter +_.where

  • 这不是递归的。 (2认同)