Como filtrar uma matriz de todos os elementos de outra matriz

Eu gostaria de entender a melhor maneira de filtrar uma matriz de todos os elementos de outra . Eu tentei com a function de filtro, mas não me vem como dar os valores que eu quero remover.
Algo como:

var array = [1,2,3,4]; var anotherOne = [2,4]; var filteredArray = array.filter(myCallback); // filteredArray should now be [1,3] function myCallBack(){ return element ! filteredArray; //which clearly can't work since we don't have the reference <,< } 

Caso a function de filtro não seja útil, como você implementaria isso?
Edit: eu verifiquei a possível questão duplicada, e poderia ser útil para aqueles que entendem o javascript facilmente. A resposta marcada como boa facilita as coisas.

Você pode usar o parâmetro this da function filter () para evitar armazenar sua matriz de filtros em uma variável global.

 var filtered = [1, 2, 3, 4].filter( function(e) { return this.indexOf(e) < 0; }, [2, 4] ); 

Eu faria o seguinte;

 var arr = [1,2,3,4], brr = [2,4], res = arr.filter(f => !brr.includes(f)); console.log(res); 
 var array = [1,2,3,4]; var anotherOne = [2,4]; var filteredArray = array.filter(myCallBack); function myCallBack(el){ return anotherOne.indexOf(el) < 0; } 

No retorno de chamada, você verifica se cada valor de array está em anotherOne

https://jsfiddle.net/0tsyc1sx/

Se você estiver usando o lodash.js , use _.difference

 filteredArray = _.difference(array, anotherOne); 

Demonstração

Se você tiver uma matriz de objects:

 var array = [{id :1, name :"test1"},{id :2, name :"test2"},{id :3, name :"test3"},{id :4, name :"test4"}]; var anotherOne = [{id :2, name :"test2"}, {id :4, name :"test4"}]; var filteredArray = array.filter(function(array_el){ return anotherOne.filter(function(anotherOne_el){ return anotherOne_el.id == array_el.id; }).length == 0 }); 

Matriz de demonstração de objects

Demo diff array de objects com lodash

  /* Here's an example that uses (some) ES6 Javascript semantics to filter an object array by another object array. */ // x = full dataset // y = filter dataset let x = [ {"val": 1, "text": "a"}, {"val": 2, "text": "b"}, {"val": 3, "text": "c"}, {"val": 4, "text": "d"}, {"val": 5, "text": "e"} ], y = [ {"val": 1, "text": "a"}, {"val": 4, "text": "d"} ]; // Use map to get a simple array of "val" values. Ex: [1,4] let yFilter = y.map(itemY => { return itemY.val; }); // Use filter and "not" includes to filter the full dataset by the filter dataset's val. let filteredX = x.filter(itemX => !yFilter.includes(itemX.val)); // Print the result. console.log(filteredX); 

A melhor descrição para filter function é https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/filter

Você deve simplesmente condicionar a function:

 function conditionFun(element, index, array) { return element >= 10; } filtered = [12, 5, 8, 130, 44].filter(conditionFun); 

E você não pode acessar o valor da variável antes de ser atribuído

Você pode usar o filtro e, em seguida, para a function de filtro, use uma redução da matriz de filtragem que verifica e retorna verdadeiro quando encontra uma correspondência e depois inverte quando retorna (!). A function de filtro é chamada uma vez por elemento na matriz. Você não está fazendo uma comparação de nenhum dos elementos da function em sua postagem.

 var a1 = [1, 2, 3, 4], a2 = [2, 3]; var filtered = a1.filter(function(x) { return !a2.reduce(function(y, z) { return x == y || x == z || y == true; }) }); document.write(filtered); 

Um array de filtragem mais flexível de outro array que contém propriedades de object

 function filterFn(array, diffArray, prop, propDiff) { diffArray = !propDiff ? diffArray : diffArray.map(d => d[propDiff]) this.fn = f => diffArray.indexOf(f) === -1 if (prop) { return array.map(r => r[prop]).filter(this.fn) } else { return array.filter(this.fn) } } //You can use it like this; var arr = []; for (var i = 0; i < 10; i++) { var obj = {} obj.index = i obj.value = Math.pow(2, i) arr.push(obj) } var arr2 = [1, 2, 3, 4, 5] var sec = [{t:2}, {t:99}, {t:256}, {t:4096}] var log = console.log.bind(console) var filtered = filterFn(arr, sec, 'value', 't') var filtered2 = filterFn(arr2, sec, null, 't') log(filtered, filtered2) 

Os exemplos a seguir usam o new Set() para criar uma matriz filtrada que tenha apenas elementos exclusivos:

Matriz com tipos de dados primitivos: string, number, boolean, null, undefined, symbol:

 const a = [1, 2, 3, 4]; const b = [3, 4, 5]; const c = Array.from(new Set(a.concat(b))); 

Array com objects como itens:

 const a = [{id:1}, {id: 2}, {id: 3}, {id: 4}]; const b = [{id: 3}, {id: 4}, {id: 5}]; const stringifyObject = o => JSON.stringify(o); const parseString = s => JSON.parse(s); const c = Array.from(new Set(a.concat(b).map(stringifyObject)), parseString); 

Todas as soluções acima “funcionam”, mas são menos que ideais para o desempenho e abordam o problema da mesma forma que busca linearmente todas as inputs em cada ponto usando Array.prototype.indexOf ou Array.prototype.includes . Uma solução muito mais rápida (muito mais rápida até do que uma pesquisa binária na maioria dos casos) seria ordenar os arrays e pular para frente conforme você avança conforme mostrado abaixo. No entanto, uma desvantagem é que isso exige que todas as inputs na matriz sejam números ou seqüências de caracteres. No entanto, a pesquisa binária pode, em alguns casos raros, ser mais rápida do que a pesquisa linear progressiva. Estes casos surgem do fato de que minha busca linear progressiva tem uma complexidade de O (2n 1 + n 2 ) (somente O (n 1 + n 2 ) na versão C / C ++ mais rápida) (onde n 1 é a matriz pesquisada e n 2 é o array de filtros), enquanto que a busca binária tem uma complexidade de O (n 1 ceil (log 2 n 2 )) (ceil = round up – para o teto ) e, por último, a busca indexOf tem um complexidade altamente variável entre O (n 1 ) e O (n 1 n 2 ) , com média de O (n 1 ceil (n 2 ÷ 2)) . Assim, indexOf será apenas o mais rápido, em média, nos casos de (n 1 , n 2 ) igualando {1,2} , {1,3} ou {x, 1 | x∈N} . No entanto, isso ainda não é uma representação perfeita do hardware moderno. O IndexOf é otimizado nativamente ao máximo que se possa imaginar na maioria dos navegadores modernos, tornando-o muito sujeito às leis de previsão de ramificação . Assim, se fizermos a mesma suposição em indexOf como fazemos com pesquisa progressiva linear e binária – que a matriz é pré-determinada – então, de acordo com as statistics listadas no link, podemos esperar uma aceleração de 6x para IndexOf, deslocando sua complexidade para entre O (n 1 ÷ 6) e O (n 1 n 2 ) , calculando a média para O (n 1 ceil (n 2 7 ÷ 12)) . Finalmente, observe que a solução abaixo nunca funcionará com objects porque é impossível obter o ponteiro de object interno (para comparação numérica) em javascript.

 function sortAnyArray(a,b) { return a>b ? 1 : (a===b ? 0 : -1); } function sortIntArray(a,b) { return a - b; } var Math_clz32 = Math.clz32; function filterArrayByAnotherArray(searchArray, filterArray, isInteger = false, i = 0) { if (isInteger) { // if all entries in both arrays are integers searchArray.sort(sortIntArray); filterArray.sort(sortIntArray); } else { searchArray.sort(sortAnyArray); filterArray.sort(sortAnyArray); } var searchArrayLen = searchArray.length, filterArrayLen = filterArray.length; var progressiveLinearComplexity = ((searchArrayLen<<1) + filterArrayLen)>>>0 var binarySearchComplexity= (searchArrayLen * (32-Math_clz32(filterArrayLen-1)))>>>0; // After computing the complexity, we can predict which algorithm will be the fastest if (progressiveLinearComplexity < binarySearchComplexity) { // Progressive Linear Search return searchArray.filter(function(currentValue){ while (filterArray[i] < currentValue) ++i; // +undefined = NaN, which is always false for <, avoiding an infinite loop return filterArray[i] !== currentValue; }); } else { // Binary Search return searchArray.filter(function(currentValue) { var lo = -1, hi = filterArrayLen; while (1 + lo !== hi) { const mi = (hi + lo) >> 1; if (currentValue <= filterArray[mi]) hi = mi; else lo = mi; } return filterArray[hi] !== currentValue; }); } } 

Para provar a diferença de velocidade, vamos examinar alguns JSPerfs. Para filtrar uma matriz de 16 elementos , a pesquisa binária é aproximadamente 17% mais rápida do que indexOf, enquanto filterArrayByAnotherArray é aproximadamente 93% mais rápida que indexOf. Para filtrar uma matriz de 256 elementos , a pesquisa binária é aproximadamente 291% mais rápida do que indexOf, enquanto filterArrayByAnotherArray é aproximadamente 353% mais rápida que indexOf. Para filtrar uma matriz de 4096 elementos , a pesquisa binária é aproximadamente 2655% mais rápida do que indexOf, enquanto filterArrayByAnotherArray é aproximadamente 4627% mais rápida que indexOf.

Você pode configurar a function de filtro para iterar sobre o “array de filtros”.

 var arr = [1, 2, 3 ,4 ,5, 6, 7]; var filter = [4, 5, 6]; var filtered = arr.filter( function(val) { for (var i = 0; i < filter.length; i++) { if (val == filter[i]) { return false; } } return true; } ); 
 var arr1= [1,2,3,4]; var arr2=[2,4] function fil(value){ return value !=arr2[0] && value != arr2[1] } document.getElementById("p").innerHTML= arr1.filter(fil) 
      

 function arr(arr1,arr2){ function filt(value){ return arr2.indexOf(value) === -1; } return arr1.filter(filt) } document.getElementById("p").innerHTML = arr([1,2,3,4],[2,4]) 
 

Você pode escrever uma function genérica filterByIndex () e fazer uso da inferência de tipos em TS para salvar o incômodo com a function de retorno de chamada:

digamos que você tenha sua matriz [1,2,3,4] que deseja filtrar () com os índices especificados na matriz [2,4].

 var filtered = [1,2,3,4,].filter(byIndex(element => element, [2,4])) 

a function byIndex espera a function do elemento e uma matriz e se parece com isso:

 byIndex = (getter: (e:number) => number, arr: number[]) => (x: number) => { var i = getter(x); return arr.indexOf(i); } 

resultado é então

 filtered = [1,3]