TypeScript按日期去重 保留各language最新对象
解答
首先明确你观察到的「取排序后列表最后出现的对应对象」不是巧合,这是Map的标准行为:向Map中重复插入相同key的条目时,后插入的值会直接覆盖该key对应的原有值。因此只要你保证列表按目标时间字段从小到大升序排列,同key最后保留的自然是时间最新的条目。
不过你当前的实现存在两个明显问题:
- 排序字段使用错误:你现在按
dateInsert(插入时间)排序,但需求是保留dateModified(修改时间)最新的记录,一旦出现插入时间早、但后续修改时间更晚的条目,最终结果就会不符合预期。 - 存在副作用:
Array.sort()是原地排序方法,会直接修改原数组this.segments的顺序,如果后续逻辑依赖原数组的顺序,会出现非预期bug。
更优实现方案(推荐)
不需要对全量数组做排序,仅需一次遍历即可完成去重,时间复杂度为O(n),比排序方案的O(nlogn)性能更好,尤其是数据量较大时优势更明显:
// 存储每个language对应的最新条目 const latestByLang = new Map<number, SegmentDTO>(); for (const segment of this.segments) { const currentMtime = new Date(segment.dateModified).getTime(); const existed = latestByLang.get(segment.language); // 同语言无存量记录,或当前记录修改时间更新,则替换存量 if (!existed || currentMtime > new Date(existed.dateModified).getTime()) { latestByLang.set(segment.language, segment); } } const result = [...latestByLang.values()];
这个方案的优势:
- 不会修改原数组,无副作用
- 直接以
dateModified作为判断新旧的唯一依据,不会出现字段用错的问题 - 逻辑显式透明,不需要依赖Map覆盖key的隐式行为,后续维护成本低
修正后的排序+Map实现
如果你更偏好排序后转Map的写法,至少要修正排序字段、避免原地修改原数组:
// 先浅拷贝原数组再排序,避免修改原数组;排序字段替换为dateModified升序 const sortedAsc = [...this.segments].sort( (a, b) => new Date(a.dateModified).getTime() - new Date(b.dateModified).getTime() ); const result = [...new Map(sortedAsc.map(item => [item.language, item])).values()];
附:涉及的SegmentDTO结构定义
export class SegmentDTO { dateInsert: Date; dateModified: Date; id: number; language: number; content: string; }
内容的提问来源于stack exchange,提问作者Aw3same
相关产品推荐
相关产品推荐

