Dart/Flutter 如何删除List中的重复元素(Map类型元素去重问题)
去重失败原因
Dart中Set判断元素重复的核心逻辑是依赖对象的==运算符和hashCode返回值。你当前列表中存储的是独立的Map实例,即便两个Map包含的键值对完全一致,默认的==运算符只会对比对象的内存地址,不会对比内部存储的内容,因此Set会将它们识别为完全不同的元素,直接调用toSet()或者利用Set自动去重的语法糖自然无法生效。
正确实现方案
场景1:按指定字段(userEmail)去重
这是你当前需求的最优方案,时间复杂度为O(n),性能最优:
List users = [ {"userEmail":"tintu@gmail.com"}, {"userEmail":"john@gmail.com"}, {"userEmail":"tintu@gmail.com"}, {"userEmail":"rose@gmail.com"}, {"userEmail":"john@gmail.com"}, ]; Set<String> existedEmails = {}; List finalList = users.where((user) { String email = user['userEmail'] as String; // 已经出现过的邮箱直接过滤 if (existedEmails.contains(email)) return false; existedEmails.add(email); return true; }).toList();
运行后finalList就是你期望的去重结果。
如果需要复用去重逻辑,可以封装为通用的扩展方法:
extension UniqueExtension<T> on Iterable<T> { List<T> uniqueBy<K>(K Function(T element) getKey) { final Set<K> seenKeys = {}; return where((element) => seenKeys.add(getKey(element))).toList(); } } // 调用示例 List finalList = users.uniqueBy((user) => user['userEmail']);
场景2:全Map内容对比去重
如果后续出现多字段的Map,需要所有键值对完全一致才判定为重复,可以基于官方collection库的深度相等判断实现:
import 'package:collection/collection.dart'; // 初始化深度相等判断工具 DeepCollectionEquality equality = DeepCollectionEquality(); // 自定义相等逻辑的Set LinkedHashSet customSet = LinkedHashSet( equals: equality.equals, hashCode: equality.hash, )..addAll(users); List finalList = customSet.toList();
内容的提问来源于stack exchange,提问作者Muk System
相关产品推荐
相关产品推荐

