合并后从List <model>中删除重复项

时间:2020-04-01 19:30:22

标签: flutter dart

我想在主列表中添加一个列表,并删除重复的列表,如下所示:

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}'));
}

输出如下:

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

https://dartpad.dev/上测试此代码时,List<int>的输出正常,但是List<item>的输出中有重复项。

3 个答案:

答案 0 :(得分:1)

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

在第二种情况下,您有项目对象。两个列表都具有可能具有相同属性值的对象,但是两者都是两个不同的对象。例如,下面的代码将在您的情况下正常工作,因为两个列表中的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'));

当调用包含时,它将使用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. contains method
  2. operator == method

答案 1 :(得分:0)

那是因为这两个项目:

a.add(new item(id: 2, title: 'item2'));
b.add(new item(id: 2, title: 'item2'));

是不同的。它们是2个不同对象的2个实例,它们的id和title值相同。正如documentation所言:

所有对象的默认行为是当且仅当此对象和其他对象是同一对象时才返回true。

如果要比较两个字段是否相同,则可以在item类中覆盖均等运算符:

operator ==(item other) {
    return (this.id == other.id && this.title == other.title);
  }

给出预期的输出:

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

答案 2 :(得分:0)

如果您想比较属性(例如标题),我认为您需要在列表上进行迭代

  a.addAll(
    b
      ..removeWhere((e) {
        bool flag = false;
        a.forEach((x) {
          if (x.title.contains(e.title)) {
            flag = true;
          }
        });

        return flag;
      }),
  );

如下所示,这两个列表项不同

相关问题