JS中[].filter的反转

Inverse of [].filter in JS?

本文关键字:filter JS      更新时间:2023-09-26

我意识到我可以做到:

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

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

这似乎很麻烦。

您可以使用箭头函数:

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

Lodash提供了一个拒绝函数,它与过滤器完全相反。

arr = _.reject(arr, filterFunc);
看看

lodash 的否定函数。它完全符合@Yury塔拉班科在他的评论中提到的。

用法:

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

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

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

这击败了大多数其他方法,因为不必通过使用箭头函数在任何时候重新指定上下文(this(,并使用参数对象的扩展语法相应地传递所有参数。

它也相当简洁,尽管我宁愿在过滤器函数上反转标志,或者一个单独的函数。

这个问题可能有点偏旧,但它仍然是相关的。

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

法典

数组多填充方法

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

这比填充更安全,但使用起来看起来并不那么优雅。

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

// ================================================================
// 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(', ');

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

然后,您可以简单地使此函数像这样工作:

arr = arr.filter(filterFunc);

有一些方法可以做到这一点:

例:

const randomNumbers = [10, 22, 36, 52, 58];
let NewArray = [];

1. 将其存储在新阵列中:

NewArray = randomNumbers.filter((n)=> ! (n> 22))

2. 使用 lodash 作为上面提到的 @Sascha Klatt:

NewArray = _.reject(randomNumbers , ((n)=> ! (n> 22)));

3. 做一个这样的函数:

function rejected(params) {
  randomNumbers.forEach((val) => {
    if (!params(val)) NewArray.push(val);
  });
  return NewArray;
}

4.或这个功能(几乎同上(

function rejected2(params) {
  randomNumbers.forEach((val) => {
    if (params(val)) {
    } else NewArray.push(val);
  });
  return NewArray;
}

如果你真的想这样做。您必须编写一个帮助程序函数,该函数返回返回正常输出的反转值的函数。

如何访问此功能取决于您。但我举了一些例子。

此外,我并不是说这比为需要的每个场景编写自定义筛选器函数更好。您甚至可以使用您拥有的功能(您可能想要也可能不需要此依赖项(。

// APPROACH 1: CREATE A GENERIC HELPER FUNCTION
const arr = [1,2,"a","b"];
function is_a_string( val ) {
  return typeof val === 'string';
}
function not( callback ) {
  return ( ...arg ) => !callback( ...arg );
}
console.log( arr.filter( not( is_a_string ) ) );

// APPROACH 2: EXTEND A SPECIFIC FUNCTION ( hoisting issue )
const arr = [1,2,"a","b"];
function is_a_string( val ) {
  return typeof val === 'string';
}
// note that hoisting is a thing here
is_a_string.not = ( ...args ) => !is_a_string(...args );
console.log( arr.filter( is_a_string.not ) );

// APPROACH 3: CREATE ANOTHER FUNCTION
const arr = [1,2,"a","b"];
function is_a_string( val ) {
  return typeof val === 'string';
}
function is_not_a_string( val ) {
  return !is_a_string( val );
  // or just `return typeof val !== 'string'`; in a simple case like this
}
console.log( arr.filter( is_not_a_string ) );

让我们举个例子

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 car.brand === "Tata"
}
var fiteredCars = cars.filter(isTata); // retuns objects of brand Tata
console.log(fiteredCars)

与此相反,只需更改您的逻辑

var isNotTata = function(car) {
  return car.brand !== "Tata"
}
var dogs = cars.filter(isNotTata); // returns objects of brand other than Tata