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

时间:2015-04-25 02:46:58

标签: arrays json underscore.js lodash

这就是我的数据对象看起来像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;
}

1 个答案:

答案 0 :(得分:1)

此数据的问题是可能应进一步检查每个节点,这意味着您无法将筛选器整齐地应用于每个项目,因为跳过的项目本身可能需要检查嵌套类别。

但是,使用普通的javascript或者在_.reducerecursive 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让您浏览一组数据并跟踪逐渐“减少”的数据变量。在我们的示例中,我们将一组类别减少为名为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