#javascript #arrays #filter
#javascript #массивы #Фильтр
Вопрос:
Как бы я написал функцию «reverse», которая фильтровала бы элементы, не отфильтрованные исходным фильтром? Я чувствую, что это должно быть просто, но я не могу придумать решение.
let f1 = e => e > 3;
let f2 = reverse(f1);
let filteredarr = [1, 2, 3, 4, 5].filter(f2);
console.log(filteredarr); // prints [1, 2, 3]
Комментарии:
1. Добро пожаловать в SO! Вы можете попробовать отрицать логическое значение текущего фильтра… В качестве отступления рассмотрим более описательные имена функций, чем
f1
иf2
.reverse
не отображается, поэтому не совсем понятно, что он делает, хотя возможно, что он отрицает результат параметра функции. Если это так, то не используйте его, и вы получите противоположноеf2
.2. @ggorlen Я думаю, OP хочет знать, как
reverse
это должно быть реализовано. Я не верю, что он еще существует.
Ответ №1:
У меня такое чувство, что вы ищете функцию более общего назначения, которой вы можете передать любую другую функцию. В этом случае это немного сложнее, но не очень.
// Perhaps opposite is a better name, since .reverse already exists
const opposite = f => ((...args) => !f(...args));
const predicate = e => e > 3;
const arr = [1, 2, 3, 4, 5];
console.log(arr.filter(predicate));
console.log(arr.filter(opposite(predicate)));
По сути, opposite
это функция, которая возвращает другую функцию, и возвращаемое значение возвращаемой функции является логическим отрицанием возвращаемого значения первой функции.
Это ...
называется синтаксисом распространения, и в этом случае он сообщает JavaScript как принимать произвольное количество аргументов, так и отправлять через то же произвольное количество параметров.
Конечно, если вы не ищете решение общего назначения, то более простой путь — просто отрицать возвращаемое значение вашей функции на месте в .filter
вызове:
const predicate = e => e > 3;
const arr = [1, 2, 3, 4, 5];
console.log(arr.filter(predicate));
console.log(arr.filter((...args) => !predicate(...args)));
Комментарии:
1. Возможно, здесь было бы лучше использовать rest-параметры на случай, если предикат принимает больше аргументов, отличных от только текущего элемента (например, индекса), например:
const opposite = fn => (...args) => !fn(...args);
2. @NickParsons Хорошая мысль, как я мог забыть? Я обновлю свой ответ. Спасибо!
3. Чувак, вы, ребята, такие классные. Хотел бы я быть таким же умным, как вы, ребята.
Ответ №2:
Это работает, но я не знаю, это именно то, что вы ищете.
// Predicate
const isLargerThan3 = number => number > 3;
const reversePredicate = predicate => number => !predicate(number);
const filteredArray = [1, 2, 3, 4, 5].filter(reversePredicate(isLargerThan3));
console.log(filteredArray);