使用下划线js的嵌套类别搜索

Nested Category Search using underscore js

这就是我的数据对象的样子http://jsfiddle.net/303tpLtz/1

如您所见here在完成搜索时必须考虑类别中的类别

所以问题是我可以使用 _.findWhere(result.response.categories, {name: 'Arts & Entertainment'})

找到类别的顶级名称

但问题是当我需要在所提供的请求中找到提到的内容时,例如,如果我需要在 Food >

中找到一家餐馆

任何人都可以帮助我使用深度搜索功能吗?

我纠结的解决方法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;
}

此数据的问题是每个节点都可能需要进一步检查,这意味着您不能对每个项目巧妙地应用过滤器,因为跳过的项目本身可能有您需要检查的嵌套类别。

然而,使用简单的 javascript 或在 _.reduce and a bit of recursive magic 的帮助下,我们只需少量代码即可完成工作。

jsFiddle

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 让我们浏览一组数据并跟踪一个渐进的 'reduced' 数据变量。在我们的例子中,我们将一组类别缩减为一个名为 result 的新数组,该数组仅包含所有嵌套类别。为了确保我们也检查所有嵌套类别,我们递归调用 extractCategories 并使用它的结果将其添加到简化的结果数组中。

最后我们剩下的是所有类别,嵌套与否,然后我们根据 attr 匹配项进行过滤。


具有更少连接的更高性能版本:

jsFiddle

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

我们越追求性能,代码就越不简洁。

Performance comparison of all three approaches