这就是我的数据对象看起来像http://jsfiddle.net/303tpLtz/1
的方式正如您可能会看到here,搜索完成时必须考虑类别内的类别
所以问题是我可以使用_.findWhere(result.response.categories, {name: 'Arts & Entertainment'})
但问题是当我需要在提供的请求中找到提到的内容时,例如,如果我需要找到一个位于Food>内的餐馆。
有人可以帮我解决Deep搜索功能吗?
我的纠结解决方案jsFiddle:
function findDeep(cats, attrs) {
_.each(cats, function(data, i) {
var copy = data;
// delete copy.categories;
newArr.push(copy);
_.each(data.categories, function(newObj) {
var copy2 = newObj;
// delete copy2.categories;
newArr.push(copy2)
if (newObj.categories) {
_.each(newObj.categories, function(otherObj) {
var copy3 = otherObj;
// delete copy3.categories;
newArr.push(copy3)
})
}
})
});
return _.findWhere(newArr, attrs) || null;
}
答案 0 :(得分:1)
此数据的问题是可能应进一步检查每个节点,这意味着您无法将筛选器整齐地应用于每个项目,因为跳过的项目本身可能需要检查嵌套类别。
但是,使用普通的javascript或者在_.reduce和recursive magic的帮助下,我们只需要一点点代码即可完成工作。
function findMatchingCategories(cats, attrs) {
return _.filter(extractCategories(cats), attrs);
function extractCategories(cats) {
return _.reduce(cats, function (result, value) {
return result.concat([value]).concat(value.categories ? extractCategories(value.categories) : []);
}, []);
}
}
console.log(findMatchingCategories(data, { name: 'Tunnel' }));
解释:
_.reduce
让您浏览一组数据并跟踪逐渐“减少”的数据变量。在我们的示例中,我们将一组类别减少为名为result
的新数组,该数组仅包含所有嵌套类别。为了确保我们也检查所有嵌套类别,我们递归调用extractCategories
并使用它的结果将其添加到简化结果数组。
最后我们剩下的是所有类别,嵌套与否,然后根据attr
匹配进行过滤。
性能更低且版本更少的版本:
function findMatchingCategories(cats, attrs) {
return _.filter(extractCategories(cats, []), attrs);
function extractCategories(currentCats, allCats) {
_.each(currentCats, function (value) {
allCats.push(value);
if (value.categories) {
extractCategories(value.categories, allCats);
}
}, []);
return allCats;
}
}
console.log(findMatchingCategories(data, { name: 'Tunnel' }));
我们的性能越多,代码就越不简洁。