Какой наиболее эффективный способ фильтрации массива на основе содержимого другого массива?

StackOverflow https://stackoverflow.com/questions/800121

  •  03-07-2019
  •  | 
  •  

Вопрос

Допустим, у меня есть два массива: items и RemoveItems, и я хочу, чтобы все значения, найденные в 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]);
   }
}

Это то, что?О(N^2)?Есть ли более эффективный способ?

Это было полезно?

Решение

Это на самом деле O(M * N).

Возможно, вы могли бы лучше сортировать animals сначала массив, а затем выполняем двоичный поиск.Вы сможете сократить до O(N * log N) - ну это если log N < M в любом случае.

В любом случае, если вы работаете с JS и он работает на стороне клиента, просто постарайтесь свести объем данных к минимуму, иначе их браузеры будут кричать на вас при каждом запросе.

Другие советы

По сути, вам нужно эффективно вычислить разность наборов S \ T.Самый (асимптотически) самый быстрый способ, который я знаю, — это поместить T в хэш-карту (которая делает шаги |T|) и просматривать каждый s в S (что делает шаги |S|), проверяя, есть ли s в T (что равно O(1) ).Таким образом, вы доберетесь до O(|T| + |S|) шагов.

С jQuery это довольно просто:

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

mammals = $.grep(animals, is_mammal);

См. документы для $.grep и $.inArray.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top