【问题标题】:Fastest way to find if an array of object contains one of the tags查找对象数组是否包含其中一个标签的最快方法
【发布时间】:2016-05-09 23:49:26
【问题描述】:

我有一个对象数组,每个对象都包含一个属性tags,其中包含一个字符串数组

let item = {
    tags: [String],
    name: String
};

let queue = [item1, item2, ...];

我想知道查找包含特定tag(s) 的所有项目。蛮力将是 2 个 for 循环:

function findTags(tags) {
    let results = [];
    queue.forEach(function (item) {
        tags.forEach(function (tag) {
            if (item.tags.indexOf(tag) !== -1) {
                results.push(item);
            }
        });
    });

    return results;
}

有比O(N^2)更好的方式吗?

【问题讨论】:

  • 不要在内循环中使用 forEach(),因为当你找到匹配的标签时,没有办法提前跳出循环。另外我认为if语句应该是if (tags.indexOf(tag) !== -1)
  • 这个问题可能重复stackoverflow.com/q/13565751/787140
  • 我们需要查看对象字面量,因为一切都取决于数据结构和类型。

标签: javascript arrays


【解决方案1】:

使用Set 或只使用Object 来存储标签,这样您就不需要迭代标签数组来搜索标签。

一旦找到匹配项,使用Array#some 停止迭代。

由于您要过滤数组,请使用Array#filter

var tagsObj = Object.create(null);
tags.forEach(function (tag) {
    tagsObj[tag] = true;
});

return queue.filter(function (item) {
    return item.tags.some(function (tag) {
        return tagsObj[tag];
    });
});

【讨论】:

    【解决方案2】:

    我想为getFirst 实现一个,为getAll 实现一个函数。

    var queue = [
            {    			
            tags: ["tag01","tag02","tag03"],
            name: "name01"
            },
            {
            tags: ["tag04","tag05","tag06"],
            name: "name02"
            },
            {
            tags: ["tag02","tag04","tag06"],
            name: "name03"
            },
            {
            tags: ["tag01","tag03","tag05"],
            name: "name04"
            },
            ],
     getFirst = (...tags) => queue.find( o => tags.some( t => o.tags.includes(t))),
       getAll = (...tags) => queue.reduce((p,o) => tags.some( t => o.tags.includes(t)) ? p.concat(o) : p ,[]);
       
    document.write("<pre> Result for getFirst:\n" + JSON.stringify(getFirst("tag04","tag02"),null,2) + "</pre>");
    document.write("<pre> Result for getAll:\n" + JSON.stringify(getAll("tag04","tag02"),null,2) + "</pre>");

    【讨论】:

    • 在与document.write() 相同的答案中包含(...tags) =&gt; 的奖励积分。
    • p = p.concat(o) 无需重新分配p
    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多