TypeScript中如何映射数组对象并提取去重的分组值
单行实例化实现方案
方案1:给Setting类新增构造函数(推荐)
给原有Setting类添加支持初始化参数的构造函数,后续实例化可以直接传参:
class Setting { settingKey!: string; value!: string; // 新增构造函数,支持传入部分属性初始化 constructor(init?: Partial<Setting>) { Object.assign(this, init); } }
改造后map逻辑可以直接简化为:
this.settingsGroups = this.settings.map(element => { const key = element.settingKey.slice(0, element.settingKey.indexOf('.')); const value = element.settingKey.slice(element.settingKey.indexOf('.')); return new Setting({ settingKey: key, value: value }); }).filter((element, i, arr) => arr.findIndex(t => t.settingKey === element.settingKey) === i);
方案2:不改类定义,直接用Object.assign完成赋值
如果不希望修改原有Setting类的定义,可以直接在实例化时通过Object.assign一次性完成属性赋值,无需单独声明中间变量:
this.settingsGroups = this.settings.map(element => { const key = element.settingKey.slice(0, element.settingKey.indexOf('.')); const value = element.settingKey.slice(element.settingKey.indexOf('.')); return Object.assign(new Setting(), { settingKey: key, value: value }); }).filter((element, i, arr) => arr.findIndex(t => t.settingKey === element.settingKey) === i);
逻辑优化建议
你当前先映射后过滤的写法需要两次遍历数组,且filter + findIndex的时间复杂度为O(n²),数据量较大时性能较差,可以用Map一次遍历同时完成映射和去重:
this.settingsGroups = Array.from( this.settings.reduce((groupMap, element) => { const groupKey = element.settingKey.split('.')[0]; // 仅当分组未存在时写入Map,自动去重 if (!groupMap.has(groupKey)) { groupMap.set(groupKey, Object.assign(new Setting(), { settingKey: groupKey, value: element.settingKey.slice(element.settingKey.indexOf('.')) })); } return groupMap; }, new Map<string, Setting>()).values() );
另外用split拆分key的写法容错性更高,就算settingKey中存在多个.也能正确提取最前面的分组名。
内容的提问来源于stack exchange,提问作者Nicke Manarin
相关产品推荐
相关产品推荐

