【问题标题】:What's the most efficient way of filtering an array based on the contents of another array?根据另一个数组的内容过滤数组的最有效方法是什么?
【发布时间】:2010-10-22 10:57:05
【问题描述】:

假设我有两个数组,items 和 removeItems,我希望从 items 中删除 removeItems 中的任何值。

蛮力机制可能是:

var animals = ["cow","dog","frog","cat","whale","salmon","zebra","tuna"];
var nonMammals = ["salmon","frog","tuna","spider"];
var mammals = [];
var isMammal;

for(var i=0;i<animals.length;i++){
   isMammal = true;
   for(var j=0;j<nonMammals;j++){
     if(nonMammals[j] === animals[i]){
       isMammal = false;
       break;
     }
   }
   if(isMammal){
     mammals.push(animals[i]);
   }
}

这是什么? O(N^2)?有没有更有效的方法?

【问题讨论】:

    标签: javascript arrays filtering


    【解决方案1】:

    实际上是O(M * N)

    也许您可以先对animals 数组进行更好的排序,然后再进行二分搜索。你将能够减少到O(N * log N) - 好吧,那是log N &lt; M 无论如何。

    无论如何,如果您正在使用 JS 并且在客户端运行,那么请尽量将数据量保持在最低限度,否则他们的浏览器会在每次请求时对您大喊大叫。

    【讨论】:

    • 我只是在写一些关于排序列表的东西。你最终得到 nlg(n) + mlg(n) 对主列表进行排序,然后搜索主列表 m 次,这实际上是 m*lg(n) - 比 n^ 好得多2
    【解决方案2】:

    使用 jQuery 非常简单:

    function is_mammal(animal)
    {
        return $.inArray(animal, nonMammals) == -1;
    }
    
    mammals = $.grep(animals, is_mammal);
    

    请参阅 $.grep$.inArray 的文档。

    【讨论】:

    • 这很简单,但并不比 O(N^2) 更好。仅仅因为你“隐藏”了循环并不意味着 $.inArray() 和 $.grep() 没有它们。
    【解决方案3】:

    基本上你想要做的是有效地计算集合差 S \ T。我知道的(渐近)最快的方法是将 T 放入一个哈希图中(这使得 |T| 步骤)并遍历 S 中的每个 s (这使得 |S| 步骤)检查 T 中的 s(这是 O(1))。所以你得到了 O(|T| + |S|) 步骤。

    【讨论】:

    • 虽然这 is 比我的答案快,但它需要更多内存用于哈希表。处处有利有弊,对吧? :) 无论如何,我相信这是最好的解决方案,所以我 +1。
    • 是的,这就是我在那里渐近地写的原因。 ;) 我个人猜想,对于小的输入,即使平方解决方案也足够了。
    猜你喜欢
    • 2021-07-10
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多