web-dev-qa-db-fra.com

Inverse de [] .filter dans JS?

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.

30
user2958725

Vous pouvez utiliser une fonction de flèche:

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

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

Vous pouvez ajouter votre propre fonction ou ajouter une méthode statique/prototype à l'objet Array.

Code

Méthodes de Polyfill 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) : [];
};

Fonction personnalisée

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)

Exemple

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

3
Mr. Polywhirl

Lodash fournit une fonction de rejet qui effectue exactement le contraire du filtre.

arr = _.reject(arr, filterFunc);
2
Sascha

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
0
Gaurav

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.

0
SEoF