Je me rends compte que je peux faire:
arr = arr.filter(function(n){ return !filterFunc(n); });
Mais y a-t-il moyen d'inverser simplement un filtre sans envelopper le filtre dans une fonction anonyme?
Cela semble juste encombrant.
Vous pouvez utiliser une fonction de flèche:
const a = someArr.filter(someFilter);
const a = someArr.filter(e => !someFilter(e));
Jetez un coup d'œil à la fonction negate de lodash. Il fait exactement ce que @Yury Tarabanko mentionne dans son commentaire.
Utilisation:
arr = arr.filter(_.negate(filterFunc));
Vous pouvez ajouter votre propre fonction ou ajouter une méthode statique/prototype à l'objet 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);
});
}
Ceci est plus sûr à utiliser qu'un polyfill, mais son utilisation n'est pas aussi élégante.
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(', ');
Lodash fournit une fonction de rejet qui effectue exactement le contraire du filtre.
arr = _.reject(arr, filterFunc);
Prenons un exemple
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
à l'inverse de cela vient de changer votre logique
var isNotTata = function(car) {
return cars.species !== "Tata"
}
var dogs = cars.filter(isNotTata); // returns objects of brand other than Tata
Je n’étais pas satisfait des réponses directement, et j’ai finalement utilisé les nouvelles fonctionnalités de JS.
arr.filter(() => ! filterfunc(...arguments));
Cela bat la plupart des autres en n'ayant pas à spécifier le contexte (this
) à tout moment en utilisant une fonction arrow et en transmettant tous les paramètres en conséquence en utilisant la syntaxe spread sur l'objet arguments .
C'est aussi assez succinct, bien que je préfère un indicateur d'inversion sur la fonction de filtrage ou une fonction séparée.
La question est peut-être un peu ancienne, mais elle reste pertinente.