我正在开发一个具有
表格中的列对应于过滤器。过滤器随时都包含来自相应列的唯一值作为选项。
对于一条记录,一列可以包含多个值(即,来自相应过滤器的多个选项)
当用户从过滤器中选择一个选项时,表中的记录将被过滤,过滤后的结果(根据用户的选择)将显示给用户。
一旦得出过滤记录集,就可以通过为每一列查找唯一值来从过滤记录集中得出每个过滤器的唯一值。
Filter对象的键对应于Record对象的列,我有一个记录列表和一个过滤器列表。我想遍历这两个列表,并找到每个键的列的唯一值。
我正在使用以下逻辑从邮件中查找过滤器的唯一选项。
export function filterOptionsService(records: Record[], filters: RecordFilter[]): RecordFilter[] {
const newFilters: RecordFilter[] = filters.map(filter => {
//logic to find all values for a column from the set of records
const filterOptions = records.reduce((uniqueList, record) => uniqueList.concat(record[filter.key]), []);
//logic to find unique values for a column from the set of records
//which act as options of corresponding filters.
const uniqueOptions = uniqBy(filterOptions, (opt) => filter.valueFunction ? filter.valueFunction(opt) : opt);
const filterOptions: FilterOption[] = uniqueOptions.map(value => {
return {
label: filter.labelFunction ? filter.labelFunction(value) : value,
value: filter.valueFunction ? filter.valueFunction(value) : value,
};
});
filter.options = orderBy(dropListOptions, 'label');
//here is my logic to find the count of each option, present in the filtered records
filter.options = filter.options.map(option => ({
...option,
count: filter.valueFunction
? filterOptions.filter(value => filter.valueFunction(value) === option.value).length
: filterOptions.filter(value => value === option.value).length
}));
return filter;
});
return newFilters;
}
interface Filter {
key: string;
labelFunction?: Function;
valueFunction?: Function;
order: number;
multiple: boolean;
options: DropListOption[];
values: DropListOption[];
}
interface Record {
column1: string;
column2: string;
column3: string | string[];
.
.
columnN: string;
}
下面的逻辑在我的代码中花费的时间最多。8k记录大约需要7秒。
const filterOptions = records.reduce((uniqueList, record) =>
uniqueList.concat(record[filter.key]), []);
我无法使我的代码性能更好。请您提出我要去哪里的建议。
我认为您遇到的性能问题是Array.prototype.concat()
不会修改现有数组,而是返回一个新数组。不变性是很好的,但是它似乎与您的用例无关:uniqueList
除了最后一个数组,您创建的每个数组都将被丢弃。在JavaScript中,对象的创建相当快,但是创建数千个数组对象只是立即将它们扔掉,这会减慢速度。
我的建议是替换concat()
为修改现有数组的内容,例如Array.prototype.push()
:
也就是说,你可以改变
const filterOptions = rows.reduce(
(uniqueList, row) => uniqueList.concat(row[filter.key]), []
);
至
const filterOptions: string[] = [];
for (let row of rows) filterOptions.push(...row[filter.key]);
当我运行模拟时,创建6000行和14个过滤器(请参见下面的操场链接),该concat()
版本大约需要7.5秒,而该push()
版本大约需要38秒milliseconds
。希望〜200改善的因素在您的环境中得以保持,并产生足以满足您需求的影响。
请注意,我没有处理您原始问题似乎具有的任何“唯一化”或“功能”方面,因为您的可复制示例代码也没有涉及到它们。通过对象键而不是数组,甚至通过,更容易计算出唯一字符串Set
。但同样,希望更改concat()
为push()
对您来说已经足够。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句