说我有一个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);
});
}
答案 0 :(得分:3)
您可以用小丑将每个字符隔开并测试字符串。
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 :(得分:0)
@Nina Scholz
的例子很棒,但实际上我会采取一些不同的方式,因为regexp s.*m.*i.*t.*h
可能会给出一些不准确的结果。
例如
搜索到的: sh 结果: John Smith
搜索: st 结果: John Smith
搜索: ji 结果: John Smith
实际上任何名字的字母和姓氏的字母,在这种情况下,结果都不准确。
我宁愿使用正则表达式.*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; }