#javascript
#javascript
Вопрос:
Допустим, у меня есть список пользователей с firstName
и lastName
и я хочу отфильтровать тех, кто соответствует либо имени, либо фамилии, либо обоим, либо любым частям, независимо от пробелов. Как бы я построил этот фильтр?
Самое близкое, что я смог получить, это
const userString = (user.firstName user.lastName user.email).toLowerCase().replace(/s/g,'');
return userString.includes(filterValue); // where filter value is the thing to test
Итак, если мы работаем с users = [John Smith, Adam Applebaum, Steve Wright]
, и я набираю «jo» или «sm», я правильно получаю «John Smith», но если я наберу «josm», я бы также хотел «John Smith», но, похоже, я не могу вернуть это.
Как я могу создать фильтр или тест, чтобы включить в него как имя, так и фамилию или любую комбинацию.
Ответ @Nina ниже работал идеально, но мне пришлось немного изменить для моего конкретного варианта использования, моя окончательная реализация была;
private _filter(value: string): User[] {
if (!value || typeof value !== 'string') { return this.users; }
const regexp = new RegExp([...(value.split(" "))].join('.*'), 'i');
return this.users.filter(user => {
const userString = user.firstName ' ' user.lastName;
return regexp.test(userString);
});
}
Комментарии:
1.попробуйте
trim
filtervalue
, и я думаю, это должно сработать2.
includes
выполняйте поиск последовательно, чтобы он соответствовалjo
илиso
правильно, но он не будет совпадатьjosm
, поскольку эти символы не появляются постоянно ни в одном из ваших имен пользователей, вам нужно использовать регулярное выражение с подстановочным знаком.*
3.
josm
Также должно совпадатьJako Some
?
Ответ №1:
Вы можете поместить каждый символ в пробел с помощью джокера и проверить строку.
function filter(array, string) {
return array.filter(RegExp.prototype.test, new RegExp([...string].join('.*'), 'i'));
}
var array = ['John Smith', 'Adam Applebaum', 'Steve Wright'];
console.log(filter(array, "jo"));
console.log(filter(array, "sm"));
console.log(filter(array, "josm"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. потрясающее спасибо, мне пришлось немного изменить, чтобы работать в моем случае, но шаблон регулярных выражений был идеальным
Ответ №2:
@Nina Scholz
пример отличный, но на самом деле я бы пошел немного другим путем, так как регулярное s.*m.*i.*t.*h
выражение может дать немного неточные результаты.
например
Поиск: sh Результаты: Джон Смит
Поиск: st Результаты: Джон Смит
Поиск: Результаты ji: Джон Смит
На самом деле любая буква из имени и любая из фамилии, и в этом случае результаты являются неточными.
Я бы предпочел использовать регулярное .*SEARCH_PHRASE.*
выражение или, если быть более точным .*smi.*
, но это личное мнение 🙂 просто хотел показать различия.
Окончательная форма будет примерно такой:
function buildPattern(str) {
const arr = [...str];
// as first item
arr.splice(0, 0, '.*');
// as last item
arr.splice(arr.length, 0, '.*');
return new RegExp(arr.join(''), 'i');
}
function filter(array, string) {
return array.filter(RegExp.prototype.test, buildPattern(string));
}
const array = ['John Smith', 'Adam Applebaum', 'Steve Wright'];
console.log(filter(array, "jo"));
console.log(filter(array, "sm"));
console.log(filter(array, "josm"));
.as-console-wrapper { max-height: 100% !important; top: 0; }