我怎样才能只保留匹配一定条件的数组的项目?

我有一个数组,我想过滤它只包括符合一定条件的项目。 这可以在JavaScript中完成吗?

一些例子:

[1, 2, 3, 4, 5, 6, 7, 8] // I only want [2, 4, 6, 8], ie 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"] 

为此,可以使用ECMAScript5中引入的Array#filter()方法。 除了IE8及更低版本以及Firefox的古老版本之外,它在所有浏览器中均受支持。 如果出于某种原因,您需要支持这些浏览器,则可以为该方法使用polyfill 。

filter()将函数作为第一个参数。 对于数组中的每一项,您的函数都传递三个参数 – 当前项的值,数组中的索引以及数组本身。 如果你的函数返回true (或真值,例如1"pizza"42 ),则该项目将被包括在结果中。 否则,它不会。 filter()返回一个新的数组 – 原始数组将保持不变。 这意味着你需要将值保存在某个地方,否则会丢失。

现在,在这个问题的例子中:

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

要过滤非严格数组的条目,因此在其原型上没有.filter属性,但仍然可以迭代(如document.getElementsByTagName ),可以使用

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

或者简写

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

至于不可迭代的对象,但你仍然想要过滤属性并获得一个通过过滤的键数组,你可以像这样与Object.keys结合使用:

 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'] 

然后,您可以创build一个包含这些属性的新对象:

 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 } 

以上甚至可以组合成一个function!

 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 } 

像这样使用:

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

遵循@Scimonster中使用ES6语法的更简洁的答案是:

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