我有一个列表对象,我从Web服务加载。我的清单以这种形式出现:
list = [ {id:"name1 Surname1" , nb:120} ,
{id:"name4 Surname4" , nb:120} ,
{id:"name2", nb:632} ,
{id:"name3Surname3", nb:102} ,
{id:"surname4", nb:896}
]
我的搜索策略是“id”。 如您所见,我有不同的格式:
用空格分隔名字 - 姓氏,仅名称,仅姓氏。
我的目的是通过id(其名称或姓氏值)搜索成员。 我的结果应该是其IDS包含我的搜索值项目的项目,即使名称和姓氏反转:名称和姓氏的顺序可能会更改
例如:
总结:
我应该搜索项目:
我尝试过 RegExp 解决方案,如下所示:
findPhones(written) {
this.splits = written.split(' ');
if (this.splits[0] === "") // Case of empty string
{
return this.filteredPhones = [];
}
this.filteredResult = List.filter((item) => {
const regex = new RegExp(written, 'gi'); // g : global & i: insentisive case
return item.List.match(regex);
});
但是这个解决方案很好,但它缺乏反转“姓氏”的条件,因为它可能会被反转:
例如:当我搜索“surname4 name4”时:我得到0结果;但实际上我应该把我列表中的第二个对象作为一个好结果:
{id:"name4 Surname4" , nb:120}
(似乎我应该结合两个过滤器操作)
有任何修复建议吗?
答案 0 :(得分:0)
注意:以下代码使用EscapeRegExp
功能。此功能在this answer中找到。 JavaScript没有像其他语言那样拥有自己的正则表达式转义函数(例如Python)。您可以使用更好的方法,但我已将此代码用作实现的基础。如果愿意,您可以随时将该功能替换为另一种功能。
list = [
{id: "name1 Surname1", nb: 120},
{id: "name4 Surname4", nb: 120},
{id: "name2", nb: 632},
{id: "name3Surname3", nb: 102},
{id: "surname4", nb: 896}
];
function Search(s) {
var searches = s.value.split(" ").filter(String);
var regex = GenerateRegExp(searches);
console.log(regex);
var matches = list.filter((i) => {
const r = new RegExp(regex, 'gi');
return r.test(i.id);
});
console.log(matches);
}
function GenerateRegExp(arr) {
var s = "";
arr.forEach(function(e) {
s += "(?=.*" + EscapeRegExp(e) + ")";
});
return s += ".*";
}
function EscapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
<input id=search type=search onkeyup="Search(this)" />
此选项比上面的正则表达式选项更强大。
list = [
{id: "name1 Surname1", nb: 120},
{id: "name4 Surname4", nb: 120},
{id: "name2", nb: 632},
{id: "name3Surname3", nb: 102},
{id: "surname4", nb: 896}
];
function Search(s) {
var searches = s.value.split(" ").filter(String);
console.log(all(searches, list));
}
function all(needles, haystacks) {
return haystacks.filter((h) => {
var string = h.id.toString().toLowerCase();
var a = needles.filter((e) => {
if (string.indexOf(e) !== -1) return e;
});
if (a.length === needles.length) return h;
});
}
<input id=search type=search onkeyup="Search(this)" />
答案 1 :(得分:0)
以下应该做你需要的。它通过检查拆分输入中的每个术语来创建匹配数组,然后检查拆分输入数组长度是否与匹配数组长度相同
const list =[ {id:"name1 Surname1" , nb:120} ,
{id:"name4 Surname4" , nb:120} ,
{id:"name2", nb:632} ,
{id:"name3Surname3", nb:102} ,
{id:"surname4", nb:896}
]
const findPhones = function(written) {
const splits = written.trim().toLowerCase().split(' ').filter(w => w);
return list.filter(o => {
const names = o.id.split(' ');
const matches = splits.filter(w => names.some(s => s.toLowerCase().includes(w)))
return names.length >= splits.length && splits.length === matches.length;
});
}
const terms = [
"name1", "surname4 name4", "name1 Surn", "Surn name1", "name1 SurAAA", "AAAA Surname1", "name1Surname1", "name"
];
terms.forEach(term=>{
console.log('Term: ', term)
console.log('Matches:', JSON.stringify(findPhones(term), null, ' '))
})
&#13;
.as-console-wrapper {top:0; max-height:none!important;height:100%;}
&#13;
答案 2 :(得分:0)
@charlietfl编写的代码使搜索不区分大小写, 当搜索的名字和姓氏不返回时,如果一个单词匹配第一个和最后一个(例如:搜索词surname4 name4不返回nb:896)
const list =[ {id:"name1 Surname1" , nb:120} ,
{id:"name4 Surname4" , nb:120} ,
{id:"name2", nb:632} ,
{id:"name3Surname3", nb:102} ,
{id:"surname4", nb:896}
]
const findPhones = function(written) {
const splits = written.trim().toLowerCase().split(' ').filter(w => w);
return list.filter(o => {
const names = o.id.split(' ');
const matches = splits.filter(w => names.some(s => s.toLowerCase().includes(w)))
return names.length >= splits.length && splits.length === matches.length;
});
}
const terms = [
"name1", "surname4 name4", "name1 Surn", "Surn name1", "name1 SurAAA", "AAAA Surname1", "name1Surname1", "name"
];
terms.forEach(term=>{
console.log('Term: ', term)
console.log('Matches:', JSON.stringify(findPhones(term), null, ' '))
})