【数组去重、分组和拷贝】

数组使用

数组使用

你提供的代码已经实现了根据 id 去重的功能,它会遍历 efTaskKmzs 数组,检查 this.efTaskList 中是否已经存在具有相同 id 的元素,如果不存在则将该元素添加到 this.efTaskList 中。

不过,你可以使用更简洁的方式来实现相同的功能,下面为你介绍几种不同的实现方法。

数组去重

方法一:使用 Map 对象

Map 对象可以存储键值对,并且键是唯一的,我们可以利用这个特性来实现去重。

javascript 复制代码
const efTaskKmzs = data.efTaskKmzs;
// 创建一个 Map 对象,用于存储已经存在的 id
const idMap = new Map(this.efTaskList.map(item => [item.id, item]));

efTaskKmzs.forEach(item => {
    if (!idMap.has(item.id)) {
        idMap.set(item.id, item);
    }
});

// 将 Map 对象的值转换为数组赋值给 this.efTaskList
this.efTaskList = Array.from(idMap.values());

方法二:使用 reduce 方法

reduce 方法可以对数组中的每个元素执行一个自定义的回调函数,并将结果累积为一个单一的值。

javascript 复制代码
const efTaskKmzs = data.efTaskKmzs;
this.efTaskList = [...this.efTaskList, ...efTaskKmzs].reduce((acc, current) => {
    // 检查累积数组中是否已经存在具有相同 id 的元素
    const existing = acc.find(item => item.id === current.id);
    if (!existing) {
        // 如果不存在,则将当前元素添加到累积数组中
        acc.push(current);
    }
    return acc;
}, []);

方法三:使用 filter 方法

filter 方法会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。

javascript 复制代码
const efTaskKmzs = data.efTaskKmzs;
const combinedList = [...this.efTaskList, ...efTaskKmzs];
this.efTaskList = combinedList.filter((item, index, self) => {
    // 检查当前元素的索引是否是第一次出现该 id 的元素的索引
    return index === self.findIndex(t => t.id === item.id);
});

以上三种方法都可以实现根据 id 对数组元素进行去重的功能,你可以根据自己的喜好选择合适的方法。

数组分组

一、自定义的分组数组

用 JavaScript 实现的通用分组函数,它可以根据指定的键对数组进行分组,并且支持传入分组类型数组来控制分组的顺序和包含的分组:

javascript 复制代码
function groupBy(arr, key, groupTypes = []) {
    const grouped = {};
    // 如果提供了分组类型数组,先初始化分组对象
    if (groupTypes.length > 0) {
        groupTypes.forEach(type => {
            grouped[type] = [];
        });
    }
    arr.forEach(item => {
        const groupValue = item[key];
        if (!grouped[groupValue]) {
            grouped[groupValue] = [];
        }
        grouped[groupValue].push(item);
    });

    return grouped;
}
// 示例数据
const people = [
    { name: '张三', gender: '男' },
    { name: '李四', gender: '女' },
    { name: '王五', gender: '男' }
];
// 根据性别分组
const groupedByGender = groupBy(people, 'gender', ['男', '女']);
console.log(groupedByGender);

二、自定义的分组函数

JavaScript 通用分组函数,它支持传入一个函数作为第三个参数,以此实现根据不同条件进行分组:

javascript 复制代码
function groupBy(arr, key, groupFunction) {
    const grouped = {};
    arr.forEach(item => {
        const groupValue = groupFunction(item[key]);
        if (!grouped[groupValue]) {
            grouped[groupValue] = [];
        }
        grouped[groupValue].push(item);
    });
    return grouped;
}
// 示例数据
const people = [
    { name: '张三', age: 18 },
    { name: '李四', age: 22 },
    { name: '王五', age: 30 },
    { name: '赵六', age: 26 }
];
// 定义分组函数
const ageGroupFunction = (age) => {
    if (age >= 0 && age < 20) {
        return '0 - 20';
    } else if (age >= 20 && age < 25) {
        return '20 - 25';
    } else if (age >= 25 && age < 36) {
        return '25 - 36';
    }
    return '其他';
};

// 根据年龄分组
const groupedByAge = groupBy(people, 'age', ageGroupFunction);
console.log(groupedByAge);

数组拷贝

在 JavaScript 中,数组的浅拷贝和深拷贝是处理数组复制时的重要概念,它们在复制数组时有着不同的行为和应用场景,下面为你详细介绍。

一、浅拷贝

浅拷贝会创建一个新的数组对象,但新数组中的元素仍然是原数组元素的引用。这意味着,如果原数组中的元素是对象或其他引用类型,那么新数组和原数组中的这些元素会指向同一个内存地址。对其中一个数组中引用类型元素的修改会影响到另一个数组。

实现浅拷贝的方法
  • slice() 方法slice() 方法可以从原数组中提取部分元素并返回一个新数组。
javascript 复制代码
const originalArray = [1, 2, { value: 3 }];
const shallowCopy = originalArray.slice();

// 修改原数组中的对象元素
originalArray[2].value = 4;

console.log(shallowCopy[2].value); // 输出: 4
  • concat() 方法concat() 方法用于合并多个数组,并返回一个新数组。
javascript 复制代码
const originalArray = [1, 2, { value: 3 }];
const shallowCopy = [].concat(originalArray);

// 修改原数组中的对象元素
originalArray[2].value = 4;

console.log(shallowCopy[2].value); // 输出: 4
  • 扩展运算符(...:扩展运算符可以将一个数组展开为多个元素。
javascript 复制代码
const originalArray = [1, 2, { value: 3 }];
const shallowCopy = [...originalArray];

// 修改原数组中的对象元素
originalArray[2].value = 4;

console.log(shallowCopy[2].value); // 输出: 4

二、深拷贝

深拷贝会创建一个新的数组对象,并且递归地复制原数组中的所有元素,包括嵌套的对象和数组。这意味着,新数组和原数组中的元素指向不同的内存地址,对其中一个数组的修改不会影响到另一个数组。

实现深拷贝的方法
  • JSON.parse()JSON.stringify() :这是一种简单的深拷贝方法,但它有一些局限性,例如不能处理函数、undefinedSymbol 等类型。
javascript 复制代码
const originalArray = [1, 2, { value: 3 }];
const deepCopy = JSON.parse(JSON.stringify(originalArray));

// 修改原数组中的对象元素
originalArray[2].value = 4;

console.log(deepCopy[2].value); // 输出: 3
  • 递归实现深拷贝函数:可以编写一个递归函数来实现深拷贝,该函数可以处理各种类型的元素。
javascript 复制代码
function deepCopy(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }

    let copy;
    if (Array.isArray(obj)) {
        copy = [];
        for (let i = 0; i < obj.length; i++) {
            copy[i] = deepCopy(obj[i]);
        }
    } else {
        copy = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                copy[key] = deepCopy(obj[key]);
            }
        }
    }
    return copy;
}

const originalArray = [1, 2, { value: 3 }];
const deepCopyArray = deepCopy(originalArray);

// 修改原数组中的对象元素
originalArray[2].value = 4;

console.log(deepCopyArray[2].value); // 输出: 3

总结

  • 浅拷贝:适用于只需要复制数组结构,而不需要复制数组元素内容的场景,性能较高。
  • 深拷贝:适用于需要完全独立于原数组的场景,确保对新数组的修改不会影响原数组,但性能相对较低,并且实现复杂。
相关推荐
我命由我123457 分钟前
Vue 开发问题:Missing required prop: “value“
开发语言·前端·javascript·vue.js·前端框架·ecmascript·js
16年上任的CTO7 分钟前
一文讲清楚React中的key值作用与原理
前端·javascript·react.js·react key
阳火锅15 分钟前
在生产环境下,你真的有考虑到使用数组方法的健壮性吗?
前端·javascript·面试
孤月葬花魂27 分钟前
JavaScript 中的 Promise API 全面解析
前端·javascript
几道之旅27 分钟前
Electron 应用打包全指南
前端·javascript·electron
shushushu32 分钟前
Web如何自动播放音视频
前端·javascript
前端进阶者1 小时前
天地图InfoWindow插入React自定义组件
前端·javascript
扶我起来还能学_1 小时前
uniapp Android&iOS 定位权限检查
android·javascript·ios·前端框架·uni-app
爱学习的茄子1 小时前
JavaScript闭包实战:防抖的优雅实现
前端·javascript·面试
前端付豪1 小时前
9、前端日志埋点系统的架构设计
前端·javascript·架构