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

JavaScript中考虑重复项的两数组差异数组生成问题

处理带重复项的数组差集需求

你遇到的这个问题确实很典型——不管是Lodash的_.difference还是原生JS的filter + includes,它们的逻辑都是只要元素在第二个数组中存在,就全部排除,根本不考虑出现的次数,所以才会把两个1都去掉,只返回[6]。

要实现你需要的「按出现次数抵消」的效果,我们得自己处理元素的计数或者逐个匹配移除,下面给你两个实用的方案:

方案一:原生JavaScript实现(无需依赖库)

核心思路是先统计第二个数组里每个元素的出现次数,然后遍历第一个数组,遇到元素时如果还有剩余的“可抵消次数”就减少计数,否则就把这个元素加入结果数组:

function getCustomDifference(arr1, arr2) {
  // 用Map统计arr2中各元素的出现次数
  const elementCounts = new Map();
  for (const num of arr2) {
    elementCounts.set(num, (elementCounts.get(num) || 0) + 1);
  }

  const result = [];
  for (const num of arr1) {
    const remaining = elementCounts.get(num);
    if (remaining && remaining > 0) {
      // 还有可抵消的次数,减少计数
      elementCounts.set(num, remaining - 1);
    } else {
      // 没有可抵消的了,加入结果
      result.push(num);
    }
  }

  return result;
}

// 测试示例
console.log(getCustomDifference([1,1,7,6], [1,7])); // 输出: [1, 6]

方案二:结合Lodash实现(如果已经在用Lodash)

如果你项目里已经引入了Lodash,可以用它的辅助函数简化逻辑,比如通过复制第二个数组的副本,逐个匹配并移除元素:

const _ = require('lodash');

function lodashCustomDifference(arr1, arr2) {
  // 复制arr2避免修改原数组
  const tempArr = [...arr2];
  return arr1.filter(num => {
    const matchIndex = tempArr.indexOf(num);
    if (matchIndex !== -1) {
      // 找到匹配项,从临时数组中移除一个
      tempArr.splice(matchIndex, 1);
      return false;
    }
    return true;
  });
}

// 测试示例
console.log(lodashCustomDifference([1,1,7,6], [1,7])); // 输出: [1, 6]

这两个方案都能满足你的需求,而且结果的顺序和原数组保持一致(如果你不需要顺序,也可以随便调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:09:27