垫自动完成同时搜索多个字段

时间:2020-09-14 15:21:05

标签: angular angular-material

我有一个包含5000个对象的自动填充垫。每个对象都包含一个名字和一个姓氏。

无论输入的顺序如何,我都希望能够同时搜索名字和姓氏。目前,我只能同时在两个字段之一中进行搜索。

private _filterClients(value: string): any[] {
    const filterValue = value.toLowerCase();
    return this.options.filter(option => 
        option.first_name.toLowerCase().indexOf( filterValue ) > -1 || 
        option.last_name.toLowerCase().indexOf( filterValue ) > -1
   );
}

我的目标是,当我输入Bill Ga ...时,我会得到最可能的建议。如果我输入Gate Bi ...

我不确定该如何实现。非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

这是一个复杂的问题,有时我们不考虑存在复合名称。我们不能区分哪个是中间名,或者哪个是第一个姓氏,或者第二个姓氏,就像在我的国家一样,所以我将尝试这样的实现:

let filterValues : string[] = value.toLowerCase().split(" ");
let results : any[][];
let arrayAux: any[][];

/**
 * We identify which of the options contains each of the words incorporated 
 * in the filter, the idea is if we introduce 2 words, obtain an array of 2
 * positions, the first will be the options that contain the first word and the
 * next the second word, regardless of if it is in the first or last name.
 */
filterValues.forEach((filterValue : string) => {
    results.push(this.options.filter(option => 
            option.first_name.toLowerCase().indexOf( filterValue ) > -1 || 
            option.last_name.toLowerCase().indexOf( filterValue ) > -1);
});

/**
 * Once we have an array for each word entered in the filter, we must 
 * obtain the options that are repeated in all the lists.
 */
if (results.length > 0){
    arrayAux.concat(results[0]);
    
    results.forEach((result: string[]) => {
        arrayAux.concat(result);
        arrayAux = arrayAux.filter((e, i, a) => a.indexOf(e) !== i);
    });
}

return arrayAux;

一个示例,以便您理解复合名称,因为并非在所有国家都使用该复合名称,例如在我国西班牙,歌手Julio Iglesias的真名是“ JulioJoséIglesias de la Cueva”,即Julio Jose是他的名字,伊格莱西亚斯(Iglesias)是第一个姓氏,德拉古瓦(la la Cueva)是第二个姓氏。

由于这种类型的名称,有必要与过滤器中的所有单词进行比较,因为自动在过滤器的同一输入中无法知道哪个名称对应于名字,名字等