Я понимаю, что могу сделать:
arr = arr.filter(function(n){ return !filterFunc(n); });
Но есть ли способ просто инвертировать фильтр, не обертывая фильтр в функцию анона?
Это просто кажется громоздким.
Я понимаю, что могу сделать:
arr = arr.filter(function(n){ return !filterFunc(n); });
Но есть ли способ просто инвертировать фильтр, не обертывая фильтр в функцию анона?
Это просто кажется громоздким.
Вы можете использовать функцию стрелки:
const a = someArr.filter(someFilter);
const a = someArr.filter(e => !someFilter(e));
Посмотрите на функцию lodash negate. Он делает именно то, что @Yury Tarabanko упоминает в своем комментарии.
Применение:
arr = arr.filter(_.negate(filterFunc));
Вы можете либо добавить свою собственную функцию, либо добавить статические/прототипы в объект 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);
});
}
Это безопаснее использовать, чем polyfill, но он не выглядит элегантным в использовании.
unfilter(items, isFruit)
vs 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);
Давайте рассмотрим пример
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(isTata); // retuns objects of brand other than Tata
Lodash предоставляет функцию отклонения, которая выполняет полную противоположность фильтра.
arr = _.reject(arr, filterFunc);
Мы можем использовать удобный метод массивов: reverse()
, с чем-то вроде:
items = myArray.filter(myFilterFunc).reverse();