Вот решение, использующее Рамда :
const {curry, contains, __, where, filter} = R; // Ramda
const search = curry(function (statuses, emailMatch, list) {
const email = contains(emailMatch);
const status = contains(__, statuses);
return filter(where({email, status}), list);
});
const userList = [
{email: 'john@stackoverflow.com', status: 'ACTIVE'},
{email: 'david@gmail.com', status: 'ACTIVE'},
{email: 'peter@gmail', status: 'INACTIVE'},
{email: 'tom@stackoverflow.com', status: 'INACTIVE'}
];
const searchActiveUsers = search(['ACTIVE']);
const searchAllUsers = search(['ACTIVE', 'INACTIVE']);
const searchActiveSoUsers = searchActiveUsers('stackoverflow');
const searchAllGmailUsers = searchAllUsers('gmail');
console.log(searchActiveSoUsers(userList)); // john
console.log(searchAllGmailUsers(userList)); // david & peter
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
Быстрое объяснение:
Карри
Принимает функцию и возвращает функцию, которая продолжает возвращать функцию, пока не будут предоставлены все параметры. Пример:
const sum = curry((a, b, c) => a + b + c);
sum(10)(20)(30); //=> 60
sum(10, 20)(30); //=> 60
sum(10, 20, 30); //=> 60
Это позволяет создавать функции, связанные с конкретными параметрами:
const searchActiveUsers = search(['ACTIVE']);
const searchActiveSoUsers = searchActiveUsers('stackoverflow');
searchActiveSoUsers(userList); // john
содержит
Принимает значение и список и возвращает true, если значение найдено в списке: (В Ramda строки и массивы являются списками.)
contains('stackoverflow.com', 'john@stackoverflow.com'); //=> true
contains('ACTIVE', ['ACTIVE', 'INACTIVE']); //=> true
__
Это параметр-заполнитель для функций с карри. Это позволяет нам указать параметры позже:
const foundInJohn = contains(__, 'john@stackoverflow.com');
foundInJohn('stackoverflow'); //=> true
foundInJohn('gmail'); //=> false
, где
Принимает объект функций и другой объект и возвращает true, если свойства второго объекта возвращают true при применении к их соответствующим функциям в первом объекте:
const soUser = where({email: contains('stackoverflow')});
soUser({email: 'john@stackoverflow.com'}); //=> true
soUser({email: 'david@gmail.com'}); //=> false
фильтр
Это похоже на собственный метод фильтрации в прототипе Array.
const filterGmail = filter(contains('gmail'));
filterGmail(['david@gmail.com', 'john@stackoverflow.com']); //=> ['david@gmail.com']