Подтвердить что ты не робот

Обратный [].фильтр в JS?

Я понимаю, что могу сделать:

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

Но есть ли способ просто инвертировать фильтр, не обертывая фильтр в функцию анона?

Это просто кажется громоздким.

4b9b3361

Ответ 1

Вы можете использовать функцию стрелки:

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

Ответ 2

Посмотрите на функцию lodash negate. Он делает именно то, что @Yury Tarabanko упоминает в своем комментарии.

Применение:

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

Ответ 3

Вы можете либо добавить свою собственную функцию, либо добавить статические/прототипы в объект 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)

Пример

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

Ответ 4

filter возвращает элементы, которые возвращают true в вашей оценке. Если вы хотите отменить это, инвертируйте свою логику в функции, которая проверяет каждый элемент.

Затем вы можете просто заставить эту функцию работать так:

arr = arr.filter(filterFunc);

Ответ 5

Давайте рассмотрим пример

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

Ответ 6

Lodash предоставляет функцию отклонения, которая выполняет полную противоположность фильтра.

arr = _.reject(arr, filterFunc);

Ответ 7

Мы можем использовать удобный метод массивов: reverse(), с чем-то вроде:

items = myArray.filter(myFilterFunc).reverse();