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);
Antwoord 2, autoriteit 58%
U kunt de parameter this
van 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);
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 array
in anotherOne
staat
https://jsfiddle.net/0tsyc1sx/
Als je lodash.js
gebruikt, gebruik dan _.difference
filteredArray = _.difference(array, anotherOne);
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 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)))
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]
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);
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>
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>
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)
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 filter
is 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),
);