复杂但高效的JavaScript阵列过滤

时间:2017-05-31 14:43:01

标签: javascript arrays filtering

我有一大堆像这样构建的对象(人)

objects = [
  {
    firstname: 'Jo',
    lastname : 'Brown'
    mail: 'jo@brown.com',
    courses: ['en', 'fr', 'es']

    ....and a lot more...
  },
  {
    firstname: 'Jack',
    lastname : 'Black'
    mail: 'blackjack@jackblack.win',
    courses: ['en', 'fr']
    ....and a lot more...
  },
  {
    firstname: 'Jeff',
    lastname : 'Grey'
    mail: 'grey@jeff.co.uk',
    courses: ['es']
    ....and a lot more...
  },

  ...and a lot more...
]

最初我设置了另一个数组,该数组应该只包含过滤人员到上面的主数组:

objectsFiltered = objects;

我需要构建一个函数来使用

过滤该数组
  1. 应用用户(搜索输入)
  2. 键入文本字段的字符串
  3. 通过链接或下拉菜单选择的某些其他标准......
  4. 因此,我将激活的滤镜存储在另一个数组中:

    _objectsFilters = [
      {
        property: ['courses']
        value: ['es']
      },
      {
        property: ['firstname', 'lastname', 'mail']
        value: 'userStringInputGoesHere'
      }
    ]
    

    在此示例中,其属性courses (Array)包含es且其属性firstname lastname {包含mail的{​​1}}应该被过滤。

    我使用函数来获取/设置,重置这样的过滤器:

    userStringInputGoesHere

    最后,问题

    这是重置过滤器的最佳方法,以及filterObjects(人员)。我想到了两种管理方法:

    输入A

    每次数组public set objectsFilters(objectsFilters: Array<ObjectsFilters>) { for (let filter of objectsFilters) { let index = this._objectsFilters.indexOf(filter); /* add filter if not already active */ if(index === -1) { this._objectsFilters.push(filter); continue; } /* remove filter if active already */ this._objectsFilters.splice(index, 1); } } public get objectsFilters(): Array<ObjectsFilters> { return this._nobjectsFilter; } 更改时,使用另一个函数设置过滤的对象(人)。因此,该函数将始终使用包含 ALL 人员(objectsFilters)的未触摸数组并应用所有过滤器。 (效率??!)

    B型

    如果应用某个过滤器,例如上面的第一个过滤器:

    objects

    将现已过滤的人员存储在数组{ property: ['courses'], value: ['es'] }, **中并存储由于课程过滤器而无效的其余人员,如下所示:

    objectsFiltered

    通过重置某个过滤器,我可以将非活动人员复制回活动人员。

    哪种方式是正确的方法?

1 个答案:

答案 0 :(得分:0)

这看起来像是过早优化的经典案例。

在类型A中,您始终拥有相同的源数据,并始终对该数据运行一个或多个过滤器。第一个过滤器将是唯一一个针对完整数据集运行的过滤器;以后的过滤器将针对逐渐变小的集合运行(因为某些数据已经被过滤掉了。)

在类型B中,每次运行过滤器时都要修改源数据,并将过滤掉的元素存储在单独的数组中。正如您所描述的那样,它将无法工作:如果过滤器发生更改,则无法知道哪些元素需要从存储库中恢复到源数组中(因为您无法分辨哪个过滤器删除了每个对象)。我能想到的“最简单”的工作方法是为每个过滤器保留一个单独的存储,因此当过滤器X更改时,您将所有对象从X的过滤后的存储转储回源,然后重新运行过滤器X这有用但维护起来相当复杂。

首先编写简单方法。如果您没有性能问题,那就完成了。

如果确实存在性能问题,请不要直接跳到方法B:改为调整过滤器的顺序:如果给定的过滤器可能会删除比其他过滤器更多的数据,请先执行此操作。如果过滤器的计算成本很高,那就去做吧。

如果你仍然有性能问题,那么你可以进入实现方法B所涉及的英雄主义。(它不会涉及到。如果你正在处理如此多的数据客户端你有过滤它的性能问题,你已经有了更大的性能问题,只是首先下载它...)