2014-11-25 5 views
7

Ich habe ein Array, und ich möchte es filtern, um nur Elemente zu enthalten, die einer bestimmten Bedingung entsprechen. Kann dies in JavaScript gemacht werden?Wie kann ich nur Elemente eines Arrays behalten, die einer bestimmten Bedingung entsprechen?

Einige Beispiele:

[1, 2, 3, 4, 5, 6, 7, 8] // I only want [2, 4, 6, 8], i.e. the even numbers 

["This", "is", "an", "array", "with", "several", "strings", "making", "up", "a", "sentence."] // I only want words with 2 or fewer letters: ["is", "an", "up", "a"] 

[true, false, 4, 0, "abc", "", "0"] // Only keep truthy values: [true, 4, "abc", "0"] 
+6

Diese ist eine kanonische Frage, um andere als Duplikate zu schließen. – Scimonster

Antwort

15

Dazu können Sie die Array#filter() Methode, eingeführt in ECMAScript5 verwenden. Es wird in allen Browsern unterstützt, außer IE8 und älteren Versionen von Firefox. Wenn Sie diese Browser aus irgendeinem Grund unterstützen müssen, können Sie die Methode polyfill verwenden.

filter() nimmt eine Funktion als erstes Argument. Für jedes Element des Arrays wird Ihrer Funktion drei Argumente übergeben - der Wert des aktuellen Elements, sein Index im Array und das Array selbst. Wenn die Funktion true (oder einen truthigen Wert, z. B. 1, "pizza" oder 42) zurückgibt, wird dieses Element in das Ergebnis einbezogen. Sonst wird es nicht. filter() gibt ein neues Array zurück - Ihr ursprüngliches Array bleibt unverändert. Das bedeutet, dass Sie den Wert irgendwo speichern müssen, sonst ist er verloren.

nun in den Beispielen aus der Frage:

var myNumbersArray = [1, 2, 3, 4, 5, 6, 7, 8]; 
 
console.log(myNumbersArray.filter(function(num){ 
 
    return !(num % 2); // keep numbers divisible by 2 
 
})); 
 
console.log(myNumbersArray); // see - it hasn't changed! 
 

 
var myStringArray = ["This", "is", "an", "array", "with", "several", "strings", "making", "up", "a", "sentence."]; 
 
console.log(myStringArray.filter(function(str){ 
 
    return str.length < 3; // keep strings with length < 3 
 
})); 
 
console.log(myStringArray); 
 

 
var myBoolArray = [true, false, 4, 0, "abc", "", "0"]; 
 
console.log(myBoolArray.filter(Boolean)); 
 
// wow, look at that trick! 
 
console.log(myBoolArray);

Und der Vollständigkeit halber, ein Beispiel, das auch die Index-und Array-Parameter verwendet: Duplikate aus dem Array entfernen:

var myArray = [1,1,2,3,4,5,6,1,2,8,2,5,2,52,48,123,43,52]; 
 
console.log(myArray.filter(function(value, index, array) { 
 
    return array.indexOf(value) === index; 
 
}));

5

Einträge zu filtern, die nicht streng Arrays sind, und damit die auf ihren Prototyp .filter Eigenschaft nicht haben, sind aber immer noch iterable (wie document.getElementsByTagName) Sie

Array.prototype.filter.call(collection, function filterFunction(el, index, collection) { 
    ... 
}); 

Oder die Kurz

verwenden können
[].filter.call(collection, function filterFunction(el, index, collection) { 
    ... 
}); 

wie für Objekte, die nicht iterable sind, aber Sie wollen immer noch Eigenschaften filtern und eine Reihe von Schlüsseln zu erhalten, die Filterung übergeben, können Sie mit Object.keys kombinieren wie so:

var obj = { one: 1, two: 2, three: 3, four: 4 }; 
var filtered = Object.keys(obj).filter(function(key) { 
    return obj[key] % 2 === 0; 
}); //filtered == ['two', 'four'] 

Dann können Sie ein neues Objekt mit diesen Eigenschaften erstellen:

var filteredObj = filtered.reduce(function(newObj, currentKey) { 
    newObj[currentKey] = obj[currentKey]; //Add the original value to the new object 
    return newObj; //Return the new object to continue iteration 
}, {}) // Begin iteration with a blank object 

//filteredObj is now { two: 2, four: 4 } 

Das Obige kann auch in eine Funktion kombiniert werden!

function filterObject(obj, testCallback) { 
    return Object.keys(obj).filter(function(key, index, array) { 
     return testCallback(obj[key], index, array); //Call original filter but pass the property 
    }).reduce(function(newObj, currentKey) { 
     newObj[currentKey] = obj[currentKey]; //Add the original value to the new object 
     return newObj; //Return the new object to continue iteration 
    }, {}); // Begin iteration with a blank object 
} 

Und wie diese:

var obj = { one: 1, two: 2, three: 3, four: 4 }; 
var filteredObj = filterObject(obj, function(el) { return el % 2 === 0 }); 
0

Eine knappe Antwort im Anschluss an die man von @Scimonster, ES6 Syntax wäre:

// even numbers 
 
const even = [1, 2, 3, 4, 5, 6, 7, 8].filter(n => n%2 == 0); 
 
// words with 2 or fewer letters 
 
const words = ["This", "is", "an", "array", "with", "several", "strings", "making", "up", "a", "sentence."].filter(el => el.length <= 2); 
 
// truable elements 
 
const trues = [true, false, 4, 0, "abc", "", "0"].filter(v => v); 
 

 
console.log(even); 
 
console.log(words); 
 
console.log(trues);

Verwandte Themen