【前端基础】数组、对象数组去重

set 对象

在实现数组、对象数组去重之前我们要先来认识一下set对象。

在JavaScript中,Set 是一种集合(collection)对象,它允许你存储不重复的值。下面是一个简单的案例,演示如何使用 Set 对象:

// 创建一个空的 Set 对象
let mySet = new Set();

// 添加元素到 Set
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(1); // 这个值将被忽略,因为它是重复的

console.log(mySet); // 输出: Set { 1, 2, 3 }

// 检查 Set 中是否包含某个值
console.log(mySet.has(2)); // 输出: true
console.log(mySet.has(4)); // 输出: false

// 获取 Set 中的元素数量
console.log(mySet.size); // 输出: 3

// 删除 Set 中的元素
mySet.delete(2);
console.log(mySet); // 输出: Set { 1, 3 }

// 迭代 Set 中的元素
mySet.forEach(value => {
  console.log(value);
});
// 输出:
// 1
// 3

在这个例子中,mySet 是一个 Set 对象,通过 add 方法添加了一些元素,注意添加重复元素时会被忽略。使用 has 方法检查值是否存在,使用 size 获取元素数量,使用 delete 方法删除元素,最后使用 forEach 迭代集合中的每个元素。Set 的特性在实现去重、集合操作等方面非常有用。

利用 set 实现数组去重

当你需要从一个数组中去除重复的元素时,Set 是一个非常方便的工具。以下是一个利用 Set 去重的案例:

// 一个包含重复元素的数组
let arrayWithDuplicates = [1, 2, 3, 1, 2, 4];

// 使用 Set 去重
let uniqueArray = [...new Set(arrayWithDuplicates)];

console.log(uniqueArray);
// 输出: [1, 2, 3, 4]

在这个例子中,new Set(arrayWithDuplicates) 会创建一个包含数组中唯一值的 Set 对象。然后,通过使用展开运算符 ...Set 转换为数组,最终得到 uniqueArray,它包含了原始数组中的唯一值,去除了重复项。

对象数组去重

set 对象实际含义

从官方文档中可以明显看出,在 set 对象中进行去重是通过严格相等。因此对于对象数组,直接如上使用set就不合适了。
【前端基础】数组、对象数组去重_第1张图片
利用set去重的代码就相当于:

let arrayWithDuplicates = [1, 2, 3, 1, 2, 4];

// 去重数组
function deduplicateArray(array) {
  let uniqueArray = [];

  for (let i = 0; i < array.length; i++) {
    let isDuplicate = false;

    for (let j = 0; j < uniqueArray.length; j++) {
      if (array[i] === uniqueArray[j]) {
        isDuplicate = true;
        break;
      }
    }

    if (!isDuplicate) {
      uniqueArray.push(array[i]);
    }
  }

  return uniqueArray;
}

let deduplicatedArray = deduplicateArray(arrayWithDuplicates);
console.log(deduplicatedArray);
// 输出: [1, 2, 3, 4]

这个函数 deduplicateArray 遍历原始数组,并将每个元素与结果数组中的元素比较。如果没有找到重复项,就将当前元素添加到结果数组中。请注意,这个方法的时间复杂度较高,特别是在数组较大的情况下。

实现对象数组去重

不能直接使用 set 进行对象数组去重就是因为 array[i] === uniqueArray[j] 全等于和我们认为理解的对象相等含义不一样,所以只要我们进一步改写这里的相等算法,来比较两个对象是否相等,就可以实现对象数组去重了。

因此我们进一步把array[i] === uniqueArray[j]改写为一个判断对象相等的equal方法,判断对象是否相等也适用,使用递归进行比较。

// 判断是不是对象
const isObject = (val) => typeof val === 'object' && val !== null
// 自定义 equal 方法
function equal (val1, val2) {
  if (isObject(val1) && isObject(val2)) {
    const keys1 = Object.keys(val1)
    const keys2 = Object.keys(val2)
    // 如果两个对象的 key 都不相同,那肯定是不相同的
    if (keys1.length !== keys2.length) {
      return false
    }
    for (const key of keys1) {
      // 如果 val2 中都没有这个属性,那肯定也不相同
      if (!keys2.includes(key)) {
        return false
      }
      if (!equal(val1[key], val2[key])) {
        return false
      }
    }
    // 上述比较后没有发现什么不一样的地方,那么就说明是相同的
    return true
  } else {
    return val1 === val2
  }
}

对象数组去重完整 demo

let arrayOfObjects = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 2, name: 'Jane' }, // 重复的对象
  { name: 'John', id: 1 }, // 重复的对象
  { id: 1, name: 'Kate' },
  { id: 3, name: 'Doe' }
];
// 判断是不是对象
const isObject = (val) => typeof val === 'object' && val !== null
// 自定义 equal 方法
function equal (val1, val2) {
  if (isObject(val1) && isObject(val2)) {
    const keys1 = Object.keys(val1)
    const keys2 = Object.keys(val2)
    // 如果两个对象的 key 都不相同,那肯定是不相同的
    if (keys1.length !== keys2.length) {
      return false
    }
    for (const key of keys1) {
      // 如果 val2 中都没有这个属性,那肯定也不相同
      if (!keys2.includes(key)) {
        return false
      }
      if (!equal(val1[key], val2[key])) {
        return false
      }
    }
    // 上述比较后没有发现什么不一样的地方,那么就说明是相同的
    return true
  } else {
    return val1 === val2
  }
}

// 使用双循环和自定义 equal 方法去重对象数组
function deduplicateObjects (array) {
  let uniqueObjects = [];

  for (let i = 0; i < array.length; i++) {
    let isDuplicate = false;

    for (let j = 0; j < uniqueObjects.length; j++) {
      if (equal(array[i], uniqueObjects[j])) {
        isDuplicate = true;
        break;
      }
    }

    if (!isDuplicate) {
      uniqueObjects.push(array[i]);
    }
  }

  return uniqueObjects;
}

let deduplicatedArray = deduplicateObjects(arrayOfObjects);
console.log(deduplicatedArray);
// 输出 [{"id": 1,"name": "John"},{"id": 2,"name": "Jane"},{"id": 1,"name": "Kate"},{"id": 3,"name": "Doe"}]

你可能感兴趣的:(前端基础,前端)