You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:36:15