如何获取两个Model列表的差异?toSet()方法处理Model无效
解决Dart中自定义Model列表的差异计算问题
你有两个AbsentModel类型的列表:
List<AbsentModel> a = [ AbsentModel(name: "abir", id: 1), AbsentModel(name: "fahim", id: 2), AbsentModel(name: "rahim", id: 3), AbsentModel(name: "akash", id: 4), ]; List<AbsentModel> b = [ AbsentModel(name: "akash", id: 4), AbsentModel(name: "fahim", id: 2), AbsentModel(name: "rahim", id: 3), ];
需要得到列表a中不在列表b里的元素,即:
List<AbsentModel> c = [AbsentModel(name: "abir", id: 1)];
直接用toSet()无效,是因为Dart中自定义类默认的==运算符比较的是对象引用,而非内容——即使两个AbsentModel的id和name完全一致,它们也是不同的对象,所以toSet()无法识别为重复项。
方法一:重写Model的==运算符和hashCode
如果需要基于name和id判断两个AbsentModel是否相等,直接在类中重写这两个方法:
class AbsentModel { final String name; final int id; AbsentModel({required this.name, required this.id}); @override bool operator ==(Object other) => identical(this, other) || other is AbsentModel && runtimeType == other.runtimeType && name == other.name && id == other.id; @override int get hashCode => name.hashCode ^ id.hashCode; }
之后就可以用where结合toSet()来筛选差异:
List<AbsentModel> c = a.where((item) => !b.toSet().contains(item)).toList();
方法二:通过唯一标识(如id)筛选(无需修改Model)
如果id是AbsentModel的唯一标识,不需要修改Model类,直接提取b的id集合来对比:
// 先把列表b的所有id存入Set,提升查询效率 Set<int> bIds = b.map((model) => model.id).toSet(); // 筛选a中id不在bIds里的元素 List<AbsentModel> c = a.where((model) => !bIds.contains(model.id)).toList();
这种方法效率更高,尤其是当列表元素较多时,因为Set的contains操作时间复杂度是O(1),而直接用b.contains(item)是O(n)。
内容的提问来源于stack exchange,提问作者Kamal Hossain
相关产品推荐
相关产品推荐

