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

Vue.js前端:API返回对象数组去重并保留关联ID及排序问题

解决Vue数组去重:保留唯一phases及关联id并排序

我太懂你踩的这个坑了——之前只处理phases去重时一切正常,结果一加上id就把重复的阶段又带回来了,本质是没把phases和id的对应关系用唯一键绑定住。下面给你一个靠谱的解决方案,兼顾去重、保留ID和排序:

核心思路

先用Map对象(或者普通对象)做中间存储,利用Map键的唯一性确保每个phases只存一次,同时把对应的id绑定到这个唯一键上;之后把Map转成目标数组,最后按阶段编号排序。

代码实现(Vue计算属性示例)

假设你的原数组存在originalArray这个data属性里,在computed里处理:

computed: {
  uniquePhasesWithId() {
    // 初始化Map,用来存唯一阶段和对应ID
    const phaseMap = new Map();

    // 遍历原数组:只保留每个阶段第一次出现的ID(要保留最后一次就去掉if判断)
    this.originalArray.forEach(item => {
      if (!phaseMap.has(item.phases)) {
        phaseMap.set(item.phases, item.id);
      }
    });

    // 把Map转成[{ phases: 'xxx', id: 'xxx' }]格式的数组
    const uniqueList = Array.from(phaseMap, ([phases, id]) => ({ phases, id }));

    // 按阶段编号排序(适配两种常见场景)
    return uniqueList.sort((a, b) => {
      // 场景1:阶段是带文字的格式,比如"阶段1"、"Phase 3"
      const numA = parseInt(a.phases.match(/\d+/)[0], 10);
      const numB = parseInt(b.phases.match(/\d+/)[0], 10);
      // 场景2:阶段是纯数字/数字字符串,比如"1"、2,直接替换上面两行:
      // const numA = Number(a.phases);
      // const numB = Number(b.phases);
      return numA - numB;
    });
  }
}

关键细节解释

  1. 为什么用Map?
    Map的键是唯一的,比普通对象更灵活(支持字符串、数字甚至对象当键),能完美避免phases重复的问题。如果你的phases都是字符串/数字,用普通对象也可以,写法类似:const phaseObj = {}; if (!phaseObj[item.phases]) phaseObj[item.phases] = item.id;

  2. ID保留规则
    上面代码默认保留每个phases第一次出现的ID,如果你的需求是保留最后一次出现的,直接去掉if (!phaseMap.has(item.phases))判断,每次遍历都覆盖Map里的对应值就行。

  3. 排序适配
    代码里写了两种场景的排序逻辑,根据你的phases实际格式选一种就行:带文字的用正则提取数字,纯数字的直接转Number比较。

内容的提问来源于stack exchange,提问作者Matt Larsuma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:22:23