【问题标题】:How can I only keep items of an array that match a certain condition?我怎样才能只保留符合特定条件的数组项?
【发布时间】:2015-01-23 18:25:26
【问题描述】:

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

一些例子:

[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"]

【问题讨论】:

  • 这是一个规范问题,用于关闭其他人作为副本。

标签: javascript arrays filter


【解决方案1】:

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

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

现在,在问题的示例中:

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

为了完整起见,还有一个使用索引和数组参数的示例:从数组中删除重复项:

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

【讨论】:

    【解决方案2】:

    要过滤不是严格数组的条目,因此它们的原型上没有.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']
    

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多