首页 > 解决方案 > Remove duplicate from List after merge

问题描述

I want to add a list to my main List and remove duplicate, like this:

class item {
  int id;
  String title;
  item({this.id, this.title});
}

void main() {
  // this is working for List<int>
  List<int> c = [1, 2, 3];
  List<int> d = [3, 4, 5];
  c.addAll(d..removeWhere((e) => c.contains(e)));
  print(c);

  // but this is not working for List<item>
  List<item> a = new List<item>();
  a.add(new item(id: 1, title: 'item1'));
  a.add(new item(id: 2, title: 'item2'));

  List<item> b = new List<item>();
  b.add(new item(id: 2, title: 'item2'));
  b.add(new item(id: 3, title: 'item3'));

  a.addAll(b..removeWhere((e) => a.contains(e)));
  a.forEach((f) => print('${f.id} ${f.title}'));
}

and output is like this:

[1, 2, 3, 4, 5]
1 item1
2 item2
2 item2
3 item3

As you test this code on https://dartpad.dev/ output is ok for List<int> but there is duplicate in output for List<item>.

标签: flutterdart

解决方案


第一个列表具有整数值,当您调用 contains 时,它将检查值并正常工作。

在第二种情况下,您有项目对象。两个列表都有可能具有相同属性值但都是两个不同对象的对象。例如,下面的代码将在您的情况下正常工作,因为 item2 对象在两个列表中是相同的。

Item item2 = Item(id: 2, title: 'item2');

List<Item> a = new List<Item>();
a.add(new Item(id: 1, title: 'item1'));
a.add(item2);

List<Item> b = new List<Item>();
b.add(item2);
b.add(new Item(id: 3, title: 'item3'));

当您调用 contains 时,它将使用 Object.== 方法,因此要处理此问题,您必须覆盖该方法并指定您自己的相等逻辑。

class Item {
  int id;
  String title;
  Item({this.id, this.title});

  @override
  bool operator == (Object other) {
    return
       identical(this, other) ||
       other is Item &&
       runtimeType == other.runtimeType &&
       id == other.id;
  }
}

或者您可以使用equatable包更好地处理它。

参考:

  1. 包含方法
  2. 运算符 == 方法

推荐阅读