Javascript 过滤大型阵列(3000+;)对象

Javascript 过滤大型阵列(3000+;)对象,javascript,angular,Javascript,Angular,我有一个json文件,其中列出了大约3000个对象。每一个物体都是一个机场。我想创建一个函数,用户可以通过键入名称过滤出单个机场 这就是我想到的 <input (keyup)="searchAirport(searchquery)" [(ngModel)]="searchquery" id="searchAirport"/> <span>{{searchedAirport}}</span> 这会返回正确的Aiport名称,但有两个缺点。只有在使用大写字母搜索

我有一个json文件,其中列出了大约3000个对象。每一个物体都是一个机场。我想创建一个函数,用户可以通过键入名称过滤出单个机场

这就是我想到的

<input (keyup)="searchAirport(searchquery)" [(ngModel)]="searchquery" id="searchAirport"/>
<span>{{searchedAirport}}</span>
这会返回正确的Aiport名称,但有两个缺点。只有在使用大写字母搜索时,它才有效。所以
barcelona
不会返回任何内容,但是
barcelona
会返回

第二个缺点是,只有当值完全等于机场名称时,它才会返回

如何基于部分搜索返回值?因此,用
Bar
代替
Barcelona
,我怎样才能解决资金问题呢?

忽略案例:

value.toLowerCase()==i.name.toLowerCase()


对于部分搜索,您可能需要使用正则表达式(Regex)

您可以按以下方式使用Regex

让arr=['abc','abd','Abe','bcd','cde','edf'];
让输入='ab';
设re=newregexp('^'+输入'i');
让结果=arr.filter(e=>e.match(re)!=null);

控制台日志(结果)我会尝试以下方法:

const findMatches = (values) => test => {
  const regex = new RegExp(test, 'i'); 
  return values.filter(val => regex.test(val.name))
}

const searchAirports = findMatches(airports);
performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

显然,您可以内联
findMatches
函数,但我认为这样更可读。

要在前端搜索大量数据,我在javascript端就是这么做的-

  • 假设您的数据数组(JSON对象)看起来像
    ['abcd','abfer','xyds','irkd',…]
    (超过100000个元素)-
    array1

  • 当您从json加载数组时,创建一个javascript数组,它是一个26长度的二维数组,并在每个索引处存储每个字符的元素索引。例如,对于上述数组,您的新数组如下-
    [[0,1],[0,1],[0],[0,2,3],[1],[1],[],[],…]
    -
    数组2
    意思-字符“a”存在于第0个元素和第1个元素中,字符“d”存在于第0、2、3个元素中

    现在,您的对象已准备就绪,页面已准备好进行快速搜索

  • 当用户键入搜索字符串时,onkeyup可以执行此操作-

  • 假设用户搜索
    'bf'

  • 从步骤2中的数组中,加载char
    b
    和char
    f
    的数组,并取两者的交点。现在,您将获得所有元素的所有位置,这些元素具有char
    b
    和char
    f
    -
    相交

  • 现在,在交集数组上进行迭代,直接在原始数组中的索引处进行操作(从步骤1开始),然后执行indexOf('bf')

    //伪代码
    var t=0;
    $。每个(相交,函数(k,v){
    if(array1[k].indexOf(searchString)>-1){
    结果[t++]=array1[k];
    }
    });
    返回结果

  • 这样,就不会迭代数组中的所有元素。您只迭代将让chars用户搜索的元素


    要提供不区分大小写的搜索,请将所有内容转换为小写()
    ,同时准备
    阵列2
    ,并在搜索时执行以下操作:

    const findMatches = (values) => test => {
      const regex = new RegExp(test, 'i'); 
      return values.filter(val => regex.test(val.name))
    }
    
    const searchAirports = findMatches(airports);
    
    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) =>
              product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
    }
    

    这将执行不区分大小写的筛选,并返回包含任何已定义文本的所有项目。

    检查以下示例代码。这可能对你有帮助

    filterData(search){
    
        var data = [{
                "id":1,
                "category":"mycategory"
               },
               {        
                    "id":2,
                    "category":"second"
                },
                {
                    "id":3,
                    "category": "thirdcat"
                }];
    
        return returnedData = $.grep(data, function(element, index){
            search = search.toLowerCase();
            var elementCategory = element.category.toLowerCase();
            if(elementCategory.indexOf(search) !== -1){
                return element;
            }
    
        });
    
    
    }
    

    如果它们是以Bar开头的多个匹配怎么办?那么它应该返回其中包含
    Bar
    的所有结果。因此,用户只需键入即可获得更具体的结果。@Caramiriel的可能重复:虽然存在一些重叠,但我不会将其称为重复。如果没有其他问题,这将增加筛选列表的整个问题。当我使用数组时,它工作正常,但当我使用数组时,我得到
    错误类型ERROR:e.match不是一个函数
    。我的数组中的对象看起来像“代码> {ID:100”,IATA:“YOW”,ICAO:“CyOW”,Lon:“-75.669167”,…<代码>尝试.E.No.MatCH(),而不是<代码> E匹配(RE)= null (有或没有<代码> No.<代码>属性),您是否考虑过“代码> re?测试(E.NoD))。
    对于
    过滤器
    ,哪个似乎是更好的选择?