Javascript Underline.js findWhere嵌套对象

Javascript Underline.js findWhere嵌套对象,javascript,underscore.js,lodash,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

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

{
  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'
      }
    }
  }
}
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);
_.findDeep(testItem, { 'path': 'folderName/sub-child.html' })
它可以深入到有子文件夹的6-7级

我想找到路径等于我提供的字符串的对象。不管它有多深

我使用的下划线仅用于顶层:

_.findWhere(files,{path:'./about2.html'}

如何进行深度嵌套搜索。下划线是否对此有所帮助,或者我是否需要使用递归构建一个mixin

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

{
  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'
      }
    }
  }
}
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);
_.findDeep(testItem, { 'path': 'folderName/sub-child.html' })

编辑

假设这样做有效,您可能需要创建一个函数
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;
}
注意这里,
recursiveFilter
使用



这不是最漂亮的代码,但我测试了它,它似乎按照您的要求工作。它设置为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'
      }
    }
  }
}
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);
_.findDeep(testItem, { 'path': 'folderName/sub-child.html' })
实施:

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);

}

这已经有了一个公认的答案,但另一个答案非常清晰,非常适合我的类似情况:
.filter
+
.where

虽然接受的答案有效,但它太通用了-它搜索对象的所有属性以查找子对象。我建议引入一个额外的参数,称为“recursProperty”,它将被认为深入到对象中。此解决方案还设置为用作lodash/下划线混合,并扩展lodash/下划线功能

_.findDeep = function(collection, predicate, recursProperty){
    let items = [];
    _.each(collection, each => items.push(each));
    return _.find(items, function(value, key, coll){
        if (predicate(value, key, coll)){
            return true;
        } else {
            _.each(value[recursProperty], each => items.push(each));
        }
    });
};
它可以用作任何其他下划线函数。e、 g,

_.findDeep(self.baseEntities, baseEntity => baseEntity.id === 71, 'entity');

如果不为'recursProperty'参数提供正确的值或提供null/undefined,则只会使搜索仅在第一级进行(不深入)。

是否可以在没有'subl child.html'硬编码的情况下进行搜索?@Wes当然,我想,只需将其作为另一个参数添加到
searchText
旁边?请参见此处:抱歉,我想找到path==string的对象。不管它的顶层还是100层深。这里没有两个字符串。如果找到一个值,lodash将从循环中中断返回false,不确定下划线是否支持该值,查看代码,返回{}可能会导致其中断,但我不确定。很好的解决方案,效果很好。我想知道为什么在默认情况下这没有内置到US/LD中@你能详细说明一下吗?我不相信,因为循环在对象中也是可能的——所以,nust遵循路径……这不是递归的。