优秀的编程知识分享平台

网站首页 > 技术文章 正文

碎片时间学编程「59]:如何比较 JavaScript 中的两个数组?

nanyue 2024-08-01 22:42:34 技术文章 5 ℃


编辑切换为居中

添加图片注释,不超过 140 字(可选)

平等比较

在 JavaScript 中使用松散或严格相等运算符(=====)比较两个数组通常会导致false,即使两个数组包含相同顺序的相同元素。这是因为数组和对象在 JavaScript 中是按引用而不是按值进行比较的,这意味着此解决方案不会产生所需的结果:

const a = [1, 2, 3]; const b = [1, 2, 3];  a === b; // false

JSON.stringify

许多人建议的常见解决方案是使用JSON.stringify(). 这允许我们序列化每个数组,然后比较两个序列化的字符串。一个简单的实现可能看起来像这样:

const equals = (a, b) => JSON.stringify(a) === JSON.stringify(b);

const a = [1, 2, 3];
const b = [1, 2, 3];

equals(a, b); // true

虽然这似乎是一个很棒的、简短且易于理解的解决方案,但它在不同值的序列化字符串相同的某些边缘情况下存在不足。例如:

const str = 'a';
const strObj = new String('a');
str === strObj; // false
equals([str], [strObj]); // 应该是 true, 将返回 false

null === undefined; // false
equals([null], [undefined]); // 应该是 true, 将返回 false

虽然这些情况似乎并不常见,但它们可能会导致一些非常烦人的问题,这些问题很难追踪和修复。这就是为什么不建议在大多数用例中使用此解决方案的原因。

更好的方法

更好的方法是比较两个数组length并用于Array.prototype.every()比较两者的值:

const equals = (a, b) =>
  a.length === b.length &&
  a.every((v, i) => v === b[i]);

const a = [1, 2, 3];
const b = [1, 2, 3];
const str = 'a';
const strObj = new String('a');

equals(a, b); // true
equals([str], [strObj]); // false
equals([null], [undefined]); // false

这种方法可以防止上述序列化问题。但是它没有考虑需要递归检查的嵌套数组或对象。对于处理此问题和其他问题的强大解决方案,您应该使用 equals 代码段。

比较乱序

最后,在某些情况下,每个数组中元素的顺序并不重要,我们只关心两个数组中存在的相同值。对于这些情况,您可以使用Set 和 Array.prototype.filter()结合循环来迭代唯一值并检查每个值是否在每个数组中出现相同的次数:

const equalsIgnoreOrder = (a, b) => {
  if (a.length !== b.length) return false;
  const uniqueValues = new Set([...a, ...b]);
  for (const v of uniqueValues) {
    const aCount = a.filter(e => e === v).length;
    const bCount = b.filter(e => e === v).length;
    if (aCount !== bCount) return false;
  }
  return true;
}

更多内容请访问我的网站:https://www.icoderoad.com

最近发表
标签列表