
在前端开发中,尤其是在处理从后端获取的数据时,我们经常会遇到需要对数组中的对象进行去重操作的需求。例如,给定一个包含多个对象的数组,我们希望根据某个特定的键(如id、category或示例中的trip_class)来确保最终数组中该键的值是唯一的,即使其他属性不同。这在vuex等状态管理库中,通常通过计算属性(computed properties)来实现,以确保数据的响应式和派生性。
原始问题中展示了一种尝试使用Array.prototype.reduce结合Array.prototype.find进行去重的方法,但未能达到预期效果。让我们分析一下其核心问题所在:
flightsClasses.reduce((acc, obj)=>{
  var exist = acc.find((flightClass) => obj.trip_class === flightClass ); // 问题所在
  if(!exist){
    acc.push(obj);
  }
  return acc;
},[]);这里的关键在于acc.find((flightClass) => obj.trip_class === flightClass )这一行。在find的回调函数中,flightClass是acc数组中的一个对象(例如 {name: 'john', trip_class: 0, ...}),而obj.trip_class是一个原始值(例如 0、1、2)。将一个原始值与一个对象进行严格相等(===)比较,结果通常会是false,除非flightClass本身就是那个原始值,这在当前上下文中是不可能的。因此,find总是找不到匹配项,导致所有对象都被添加到acc中,最终返回一个未去重的数组。
要正确地使用find来检查唯一性,我们需要比较对象中对应的键值。将acc.find((flightClass) => obj.trip_class === flightClass )修正为acc.find((flightClass) => obj.trip_class === flightClass.trip_class )即可。
以下是修正后的computed属性实现:
立即学习“前端免费学习笔记(深入)”;
// 假设这是您的Vue组件或Vuex Getter
computed: {
    flights() {
        // 从Vuex store获取原始航班数据
        return this.$store.getters.getFlights;
    },
    flightsClassesUnique() {
        const allFlights = this.flights; // 获取原始数据,避免直接修改
        if (!allFlights || allFlights.length === 0) {
            return [];
        }
        // 使用 reduce 方法进行去重
        const uniqueFlights = allFlights.reduce((accumulator, currentObject) => {
            // 检查累加器中是否已存在具有相同 trip_class 的对象
            const exists = accumulator.find(
                (itemInAccumulator) => currentObject.trip_class === itemInAccumulator.trip_class
            );
            // 如果不存在,则将当前对象添加到累加器中
            if (!exists) {
                accumulator.push(currentObject);
            }
            return accumulator;
        }, []); // 初始累加器为空数组
        console.log('uniqueFlights:', uniqueFlights);
        return uniqueFlights;
    }
}示例数据输入:
[
    {name: 'john', trip_class: 0, lastname: 'lastname'},
    {name: 'Don', trip_class: 1, lastname: 'lastname'},
    {name: 'Joshua', trip_class: 1, lastname: 'lastname'},
    {name: 'Mary', trip_class: 2, lastname: 'lastname'}
]期望的输出:
[
    {name: 'john', trip_class: 0, lastname: 'lastname'},
    {name: 'Don', trip_class: 1, lastname: 'lastname'},
    {name: 'Mary', trip_class: 2, lastname: 'lastname'}
]通过上述修正,find方法将正确地比较trip_class的值,从而实现根据该键去重的目的。
除了reduce与find的组合,还有其他更高效或更简洁的方法来实现对象数组去重,尤其是在处理大型数据集时,性能差异会更加明显。
Map对象可以存储键值对,并且键可以是任何类型(包括对象引用),但在这里我们利用它的特性来存储唯一的trip_class值。这种方法通常比reduce结合find更高效,因为它避免了每次迭代时对accumulator数组进行线性搜索。
computed: {
    flightsClassesUniqueByMap() {
        const allFlights = this.flights;
        if (!allFlights || allFlights.length === 0) {
            return [];
        }
        const uniqueMap = new Map();
        allFlights.forEach(flight => {
            // 使用 trip_class 作为 Map 的键,如果键不存在,则添加该对象
            if (!uniqueMap.has(flight.trip_class)) {
                uniqueMap.set(flight.trip_class, flight);
            }
            // 或者,如果总是想保留第一次出现的对象,直接 set 即可,Map会自动处理重复键
            // uniqueMap.set(flight.trip_class, flight);
        });
        // 将 Map 的值转换为数组
        return Array.from(uniqueMap.values());
    }
}说明: Map的键是唯一的。当遇到重复的trip_class时,set操作会覆盖之前的值。如果需要保留第一次出现的对象,则需要先判断!uniqueMap.has(flight.trip_class)。如果无所谓保留哪一个(例如,trip_class相同的对象其他属性也一致),则可以直接uniqueMap.set(flight.trip_class, flight);。
这种方法结合了filter的简洁性和findIndex的查找能力,或者同样利用Map来跟踪已见的键。
computed: {
    flightsClassesUniqueByFilter() {
        const allFlights = this.flights;
        if (!allFlights || allFlights.length === 0) {
            return [];
        }
        // 方法一:使用 filter 和 findIndex
        // 这种方法在大型数组上性能可能不如 Map,因为它每次都会查找原始数组
        return allFlights.filter((flight, index, self) =>
            index === self.findIndex((f) => f.trip_class === flight.trip_class)
        );
        // 方法二:使用 filter 和 Set (如果去重键是原始类型)
        // const seen = new Set();
        // return allFlights.filter(flight => {
        //     const duplicate = seen.has(flight.trip_class);
        //     seen.add(flight.trip_class);
        //     return !duplicate;
        // });
    }
}说明:
通过本文的讲解,您应该能够理解在Vuex中如何正确且高效地根据对象键值获取唯一数组。根据您的具体需求和数据量,选择最适合的去重策略,以构建健壮、高效的Vue应用。
以上就是在Vuex应用中根据对象键值获取唯一数组的策略与实践的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                 
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                            Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号