Hoe een array te filteren van alle elementen van een andere array

Ik wil graag weten wat de beste manier is om een array te filteren van alle elementen van een andere. Ik heb geprobeerd met de filterfunctie, maar het komt er niet in me op hoe ik het de waarden moet geven die ik wil verwijderen.
Zoiets als:

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 <,< 
}

Als de filterfunctie niet nuttig is, hoe zou u dit dan implementeren?

Bewerken: ik heb de mogelijke dubbele vraag gecontroleerd, en het kan nuttig zijn voor degenen die javascript gemakkelijk begrijpen. Het antwoord dat als goed is aangevinkt, maakt het gemakkelijk.


Antwoord 1, autoriteit 100%

Ik zou het als volgt doen;

var arr1 = [1,2,3,4],
    arr2 = [2,4],
    res = arr1.filter(item => !arr2.includes(item));
console.log(res);

Snippet uitvouwen


Antwoord 2, autoriteit 58%

U kunt de parameter thisvan de functie filter()gebruiken om te voorkomen dat uw filterarray in een globale variabele wordt opgeslagen.

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

Snippet uitvouwen


Antwoord 3, autoriteit 18%

var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(myCallBack);
function myCallBack(el){
  return anotherOne.indexOf(el) < 0;
}

In de callback controleert u of elke waarde van arrayin anotherOne

staat

https://jsfiddle.net/0tsyc1sx/

Als je lodash.jsgebruikt, gebruik dan _.difference

filteredArray = _.difference(array, anotherOne);

Demo

Als je een array van objecten hebt:

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
});

Demo-array van objecten

Demo verschillende array van objecten met lodash


Antwoord 4, autoriteit 2%

Er zijn veel antwoorden op uw vraag, maar ik zie niemand lambda-expressie gebruiken:

var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(x => anotherOne.indexOf(x) < 0);

Antwoord 5

met objectfilterresultaat

[{id:1},{id:2},{id:3},{id:4}].filter(v=>!([{id:2},{id:4}].some(e=>e.id === v.id)))

voer hier de afbeeldingsbeschrijving in


Antwoord 6

De OA kan ook als volgt in ES6 worden geïmplementeerd

ES6:

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

Antwoord 7

Hieronder staat een voorbeeld

let firstArray=[1,2,3,4,5];
let secondArray=[2,3];  
let filteredArray = firstArray.filter((a) => secondArray.indexOf(a)<0);
console.log(filteredArray); //above line gives [1,4,5]

Snippet uitvouwen


Antwoord 8

U kunt de filterfunctie instellen om de “filterarray” te herhalen.

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;
  }
); 

Antwoord 9

U kunt het filter gebruiken en vervolgens voor de filterfunctie een reductie van de filterarray gebruiken die controleert en true retourneert wanneer het een overeenkomst vindt en vervolgens omkeert bij terugkeer (!). De filterfunctie wordt eenmaal per element in de array aangeroepen. Je vergelijkt geen van de elementen in de functie in je bericht.

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);

Snippet uitvouwen


Antwoord 10

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)
<!DOCTYPE html> 
<html> 
<head> 
</head>
<body>
<p id="p"></p>

Snippet uitvouwen


Antwoord 11

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])
<p id="p"></p>

Snippet uitvouwen


Antwoord 12

Een flexibelere filterarray uit een andere array die objecteigenschappen bevat

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)

Snippet uitvouwen


Antwoord 13

Je kunt een generieke filterByIndex()-functie schrijven en gebruik maken van type-inferentie in TS om het gedoe met de callback-functie te besparen:

stel dat u uw array [1,2,3,4] heeft die u wilt filteren() met de indices gespecificeerd in de [2,4] array.

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

de functie byIndex verwacht de elementfunctie en een array en ziet er als volgt uit:

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

het resultaat is dan

filtered = [1,3]

Antwoord 14

De oplossing van Jack Giffin is geweldig, maar werkt niet voor arrays met getallen groter dan 2^32. Hieronder vindt u een aangepaste, snelle versie om een ​​array te filteren op basis van de oplossing van Jack, maar deze werkt voor 64-bits arrays.

const Math_clz32 = Math.clz32 || ((log, LN2) => x => 31 - log(x >>> 0) / LN2 | 0)(Math.log, Math.LN2);
const filterArrayByAnotherArray = (searchArray, filterArray) => {
    searchArray.sort((a,b) => a > b);
    filterArray.sort((a,b) => a > b);
    let searchArrayLen = searchArray.length, filterArrayLen = filterArray.length;
    let progressiveLinearComplexity = ((searchArrayLen<<1) + filterArrayLen)>>>0
    let binarySearchComplexity = (searchArrayLen * (32-Math_clz32(filterArrayLen-1)))>>>0;
    let i = 0;
    if (progressiveLinearComplexity < binarySearchComplexity) {
      return searchArray.filter(currentValue => {
        while (filterArray[i] < currentValue) i=i+1|0;
        return filterArray[i] !== currentValue;
      });
    }
    else return searchArray.filter(e => binarySearch(filterArray, e) === null);
}
const binarySearch = (sortedArray, elToFind) => {
  let lowIndex = 0;
  let highIndex = sortedArray.length - 1;
  while (lowIndex <= highIndex) {
    let midIndex = Math.floor((lowIndex + highIndex) / 2);
    if (sortedArray[midIndex] == elToFind) return midIndex; 
    else if (sortedArray[midIndex] < elToFind) lowIndex = midIndex + 1;
    else highIndex = midIndex - 1;
  } return null;
}

Antwoord 15

De beste beschrijving voor de functie filteris https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/filter

Je moet gewoon de functie conditioneren:

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

En je hebt geen toegang tot de waarde van de variabele voordat deze is toegewezen


Antwoord 16

In de volgende voorbeelden wordt new Set()gebruikt om een ​​gefilterde array te maken die alleen unieke elementen bevat:

Array met primitieve datatypes: 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 met objecten als items:

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);

Antwoord 17

Hier ziet u hoe u dit kunt doen als de items in de arrays objecten zijn.

Het idee is om de array van alleen de sleutels in een binnenste array te vinden met behulp van de kaartfunctie

Controleer vervolgens of de array van die sleutels een specifieke elementsleutel in de buitenste array bevat.

const existsInBothArrays = array1.filter((element1) =>
    array2.map((element2) => element2._searchKey).includes(element1._searchKey),
  );

Other episodes