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

如何实现同Unit下同Reference保留最长Duration的数组过滤?

问题需求

当数组元素属于同一个unit且拥有相同reference时,移除其余元素,仅保留duration时长最长的元素。

原始数组

const array = [
  {
    reference: 'Tet our mission not here',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 21,
  },
  {
    reference: 'Tet our mission',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 22,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:10.000', end: '2:40.403' },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:40.000', end: '2:40.403' },
    unit: 23,
  },
  {
    reference: 'we built the Tet',
    duration: { start: '2:37.345', end: '2:38.500' },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:30.000', end: '2:40.403' },
    unit: 23,
  }
];

现有问题代码

const array = [
  {
    reference: 'Tet our mission not here',
    duration: {
      start: '2:33.213',
      end: '2:35.871'
    },
    unit: 21,
  },
  {
    reference: 'Tet our mission',
    duration: {
      start: '2:33.213',
      end: '2:35.871'
    },
    unit: 22,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: {
      start: '2:10.000',
      end: '2:40.403'
    },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: {
      start: '2:40.000',
      end: '2:40.403'
    },
    unit: 23,
  },
  {
    reference: 'we built the Tet',
    duration: {
      start: '2:37.345',
      end: '2:38.500'
    },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: {
      start: '2:30.000',
      end: '2:40.403'
    },
    unit: 23,
  }
];
console.log(getLongestByUnit(array))
function getLongestByUnit(array) {
  const by_unit = {};
  array.forEach(el => {
    let old = by_unit[el.unit]
    if (!old) {
      by_unit[el.unit] = el;
    } else if (el.reference == old.reference && (getSecondsDuration(el.duration.start, el.duration.end) > getSecondsDuration(old.duration.start, old.duration.end))) {
      by_unit[el.unit] = el;
    } else {
      by_unit[el.unit] = el;
    }
  });
  let result = Object.values(by_unit);
  return result;
}
function getSecondsDuration(start, end) {
  const milisecondsDiff = (hrsToSecs(end) * 1000) - (hrsToSecs(start) * 1000);
  return milisecondsDiff / 1000;
}
function hrsToSecs(hrs) {
  var b = hrs.split(':');
  return b.length > 2 ? b[0] * 3600 + b[1] * 60 + +b[2] : b[0] * 60 + +b[1];
}

期望输出

[
  {
    reference: 'Tet our mission not here',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 21,
  },
  {
    reference: 'Tet our mission',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 22,
  },
  { // 此元素时长最长
    reference: 'we built the Tet our mission control',
    duration: { start: '2:10.000', end: '2:40.403' },
    unit: 23,
  },
  /* { 已移除
    reference: 'we built the Tet our mission control',
    duration: { start: '2:40.000', end: '2:40.403' },
    unit: 23,
  }, */
  {
    reference: 'we built the Tet',
    duration: { start: '2:37.345', end: '2:38.500' },
    unit: 23,
  },
  /* { 已移除
    reference: 'we built the Tet our mission control',
    duration: { start: '2:30.000', end: '2:40.403' },
    unit: 23,
  } */
];

修复方案

现有代码的核心问题是分组逻辑错误:仅用unit作为分组键,导致同一unit下不同reference的元素被互相覆盖,无法保留不同reference的条目;同时else分支直接覆盖旧元素的逻辑会丢失有效数据。

修改后的代码如下:

const array = [
  {
    reference: 'Tet our mission not here',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 21,
  },
  {
    reference: 'Tet our mission',
    duration: { start: '2:33.213', end: '2:35.871' },
    unit: 22,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:10.000', end: '2:40.403' },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:40.000', end: '2:40.403' },
    unit: 23,
  },
  {
    reference: 'we built the Tet',
    duration: { start: '2:37.345', end: '2:38.500' },
    unit: 23,
  },
  {
    reference: 'we built the Tet our mission control',
    duration: { start: '2:30.000', end: '2:40.403' },
    unit: 23,
  }
];
console.log(getLongestByUnit(array))
function getLongestByUnit(array) {
  // 用`unit-reference`作为组合键,区分同一unit下不同reference的组
  const groupMap = {};
  array.forEach(el => {
    const key = `${el.unit}-${el.reference}`;
    const currentDuration = getSecondsDuration(el.duration.start, el.duration.end);
    const existing = groupMap[key];
    
    if (!existing) {
      groupMap[key] = el;
    } else {
      const existingDuration = getSecondsDuration(existing.duration.start, existing.duration.end);
      // 仅当当前元素时长更长时才替换
      if (currentDuration > existingDuration) {
        groupMap[key] = el;
      }
    }
  });
  return Object.values(groupMap);
}
function getSecondsDuration(start, end) {
  const milisecondsDiff = (hrsToSecs(end) * 1000) - (hrsToSecs(start) * 1000);
  return milisecondsDiff / 1000;
}
function hrsToSecs(hrs) {
  var b = hrs.split(':');
  return b.length > 2 ? b[0] * 3600 + b[1] * 60 + +b[2] : b[0] * 60 + +b[1];
}

关键改动点

  • 分组键改为${el.unit}-${el.reference},确保同一unit下不同reference的元素被分到独立的组中
  • 移除错误的else分支覆盖逻辑,仅在当前元素时长大于组内已有元素时才替换
  • 提前计算当前元素和已有元素的时长,避免重复调用函数提升效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:26:04