复杂的,但有效的JavaScript数组过滤
我有一个非常大的阵列的对象(人)的结构这样复杂的,但有效的JavaScript数组过滤
objects = [
{
firstname: 'Jo',
lastname : 'Brown'
mail: '[email protected]',
courses: ['en', 'fr', 'es']
....and a lot more...
},
{
firstname: 'Jack',
lastname : 'Black'
mail: '[email protected]',
courses: ['en', 'fr']
....and a lot more...
},
{
firstname: 'Jeff',
lastname : 'Grey'
mail: '[email protected]',
courses: ['es']
....and a lot more...
},
...and a lot more...
]
最初予置另一阵列,其应包含过滤人员仅于上述主阵列:
objectsFiltered = objects;
我需要构建一个功能来过滤与
- 字符串通过键入到一个文本框该阵列该应用程序的用户(搜索输入)
- 某些其它准则可选择通过链接或下拉菜单...
因此我激活的过滤器存储在另一个阵列是这样的:
_objectsFilters = [
{
property: ['courses']
value: ['es']
},
{
property: ['firstname', 'lastname', 'mail']
value: 'userStringInputGoesHere'
}
]
在这个例子中的人,其财产courses (Array)
包含es
和其财产firstname
ORlastname
ORmail
包含应该过滤。
我用函数来获取/套,过滤器复位这样的:
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;
}
最后,问题
这是复位过滤器和与之的filteredObjects(人)的最佳途径。我想到了两种方式管理这样的:每次
A型
使用其他功能来设置过滤的对象(人)阵列objectsFilters
变化。因此该函数将始终使用包含ALL个人(objects
)的未修改阵列并应用所有过滤器。 (效率??!)
类型B
如果某一个过滤器从上方施加例如第一过滤器:
{
property: ['courses'],
value: ['es']
},
商店现在过滤人员阵列objectsFiltered
中**并存储由于课程过滤器而不活动的其余人员,如下所示:
objects = [
{
firstname: 'Jo',
lastname : 'Brown'
mail: '[email protected]',
courses: ['en', 'fr', 'es']
....and a lot more...
},
{
firstname: 'Jack',
lastname : 'Black'
mail: '[email protected]',
courses: ['en', 'fr']
....and a lot more...
},
{
firstname: 'Jeff',
lastname : 'Grey'
mail: '[email protected]',
courses: ['es']
....and a lot more...
},
...and a lot more...
]
_objectsFilters = [
{
property: ['courses']
value: ['es']
}
]
objectsFiltered = [
{
firstname: 'Jo',
lastname : 'Brown'
mail: '[email protected]',
courses: ['en', 'fr', 'es']
....and a lot more...
},
{
firstname: 'Jeff',
lastname : 'Grey'
mail: '[email protected]',
courses: ['es']
....and a lot more...
},
...and a lot more...
]
inactiveObjects = [
{
inactiveCause: {
property: ['courses'],
value: ['es']
},
/* containing all objects inactive because of the above filter */
objects: [
{
firstname: 'Jack',
lastname : 'Black'
mail: '[email protected]',
courses: ['en', 'fr']
....and a lot more...
},
]
}
]
这样通过re设置一个特定的过滤器我可以将非活动人员复制回活动人员。
哪种方式是正确的路?
这看起来像是过早优化的经典案例。
在类型A中,您始终拥有相同的源数据,并始终对该数据运行一个或多个过滤器。第一个过滤器将是唯一一个针对完整数据集运行的过滤器;后面的过滤器将针对逐渐变小的集合运行(因为某些数据已经被过滤掉了)。
在B类中,您每次运行过滤器时都要修改源数据,并存储过滤掉的数据元素在一个单独的数组中。正如你所描述的那样,它不起作用:如果过滤器发生变化,无法知道哪些元素需要从存储器恢复到源数组中(因为您无法知道哪个过滤器会删除每个对象)。我能想到的“最简单”的工作方法是为每个过滤器保留一个单独的存储空间,因此当过滤器X发生更改时,您需要将所有对象从过滤后的X存储回源,然后重新运行过滤器X 。这会起作用,但维护起来会相当复杂。
首先编写简单的方法A.如果你没有性能问题,你就完成了。
如果您确实有性能问题,请不要直接跳到方法B:而是调整您执行过滤器的顺序:如果给定的过滤器可能会比其他过滤器移除更多数据,请先执行此操作。如果一个过滤器在计算上花费很大,那么继续使用它。
如果你仍然有性能问题,那么你也许可以进入参与实施方法B的英雄(它不会来到这个如果你处理如此多的数据客户端,你有性能问题过滤它,你已经有更大的性能问题,只是首先下载它...)
“类型A”听起来更容易实现。就我个人而言,如果遇到性能问题,我会走这条路线并重新评估。还要考虑一个事实,即非常聪明的人已经多次解决了这些问题,而其他人的广泛使用,经过充分测试的解决方案几乎总是比我们自己写的更好。 (换句话说,以简单的方式来做,如果你发现你需要更强大的东西,不要重新发明轮子。) –