在JS中反转[] .filter?

时间:2013-11-22 15:18:32

标签: javascript arrays filter

我意识到我能做到:

arr = arr.filter(function(n){ return !filterFunc(n); });

但是有没有办法在不将过滤器包装在anon函数中的情况下反转过滤器?

这看起来很麻烦。

7 个答案:

答案 0 :(得分:20)

您可以使用箭头功能:

const a = someArr.filter(someFilter);
const a = someArr.filter(e => !someFilter(e));

答案 1 :(得分:4)

看看lodash的negate功能。它完全符合@Yury Tarabanko在评论中提到的内容。

<强>用法:

arr = arr.filter(_.negate(filterFunc));

答案 2 :(得分:2)

filter会返回评估中返回true的元素。如果你想反转它,在你测试每个元素的函数中反转你的逻辑。

然后,你可以简单地使这个功能工作:

arr = arr.filter(filterFunc);

答案 3 :(得分:2)

您可以添加自己的函数,也可以向Array对象添加静态/原型方法。

代码

阵列Polyfill方法

/**
 * The not() method creates a new array with all elements that fail
 * the test implemented by the provided function.
 *
 * Syntax
 * arr.not(callback[, thisArg])
 *
 * @param  callback
 *         Function to test each element of the array. Invoked with
 *         arguments (element, index, array). Return true to keep
 *         the element, false otherwise.
 * @param  thisArg
 *         Optional. Value to use as this when executing callback.
 * @return Returns a new array containing all the items which fail
 *         the test.
 */
Array.prototype.not = function(callback) {
    return this.filter(function () {
        return !callback.apply(this, arguments);
    });
};
/**
 * Static method which calls Array.prototype.not on the array
 * paramater.
 *
 * @see Array.prototype.not
 */
Array.not = function (array, callback) {
    return array != null ? array.not(callback) : [];
};

自定义功能

function unfilter(array, callback) {
    return array.filter(function () {
        return !callback.apply(this, arguments);
    });
}

这比使用polyfill更安全,但它看起来并不优雅。

unfilter(items, isFruit) vs items.not(isFruit)

实施例

&#13;
&#13;
// ================================================================
// Polyfill
// ================================================================
Array.prototype.not = function(callback) {
    return this.filter(function () {
        return !callback.apply(this, arguments);
    });
};

// ================================================================
// Main
// ================================================================
var items = [{
    name: 'Apple',
    isFruit: true
}, {
    name: 'Carrot',
    isFruit: false
}, {
    name: 'Melon',
    isFruit: true
}, {
    name: 'Potato',
    isFruit: false
}];

var isFruit = function(item, index) {
    return item != null && item.isFruit;
};
var getName = function(item, index) {
    return item != null ? item.name : '?';
};

document.body.innerHTML = items.not(isFruit).map(getName).join(', ');
&#13;
&#13;
&#13;

答案 4 :(得分:2)

Lodash提供了与过滤器完全相反的拒绝功能。

arr = _.reject(arr, filterFunc);

答案 5 :(得分:0)

让我们举个例子

var cars = [
  {carname: "indica", brand: "Tata"},
  {carname: "accord", brand: "Toyota"},
  {carname: "vento", brand: "volkswagen"},
  {carname: "polo", brand: "volkswagen"},
  {carname: "Manza", brand: "Tata"},
  {carname: "Agile", brand: "Chevrolet"},
];

var isTata = function(car) {
  return cars.species === "Tata"
}

var dogs = cars.filter(isTata); // retuns objects of brand Tata

反过来改变你的逻辑

var isNotTata = function(car) {
  return cars.species !== "Tata"
}

var dogs = cars.filter(isNotTata); // returns objects of brand other than Tata

答案 6 :(得分:0)

我对任何答案都不满意,实际上使用了最新的JS功能

arr.filter(() => ! filterfunc(...arguments));

这比其他大多数方法都好,因为不必在任何时候通过使用arrow function来重新指定上下文(this),并在{{ 3}}。

它也很简洁,尽管我希望在filter函数或一个单独的函数上使用一个反转标志。

这个问题可能有些陈旧,但这仍然很重要。