如何删除 List<MyDataModel> 的重复项(Dart/Flutter)

Posted

技术标签:

【中文标题】如何删除 List<MyDataModel> 的重复项(Dart/Flutter)【英文标题】:How to delete duplicates of a List<MyDataModel> (Dart/Flutter) 【发布时间】:2020-03-14 13:24:57 【问题描述】:

我有一个基于列表构建 UI 的 futurebuilder,它完成了这项工作,但是由于每次导航时都会一次又一次地构建 UI,因此我得到了重复。我的问题是,Dart 中是否有一种先天方法可以从列表中删除重复项?我试过这个*** question 但是它不起作用。

这是我的自定义模型:

class HomeList 
  Widget navigateScreen;
  String imagePath;
  PatientInfo patientInfo;

  HomeList(
    this.navigateScreen,
    this.imagePath = '',
    this.patientInfo,
  );

  static List<HomeList> homeList = [];


这是我从 cloud_firestore 获取数据的 futureBuilder 函数:

  _getPatients() async 
    if (didLoadpatients == 0) 
      print('this is didloadpatients at start of func $didLoadpatients');
      var document = await db
          .collection('users')
          .document(mUser.uid)
          .collection('patients');

      document.getDocuments().then((QuerySnapshot query) async 
        query.documents.forEach((f) 
          uids.add(f.data['uID']);
        );
        didLoadpatients++;
      print('this is didloadpatients at end of func $didLoadpatients');
        for (var i = 0; i < uids.length; i++) 
          var userDocuments = await db.collection('users').document(uids[i]);
          userDocuments.get().then((DocumentSnapshot doc) 
            print(doc.data);
            homeList.add(HomeList(
                imagePath: 'assets/fitness_app/fitness_app.png',
                patientInfo: new PatientInfo.fromFbase(doc.data)));
          );
          print(homeList);
        
      );
     else 
    print('I am leaving the get patient function');
  

  Future<bool> getData() async 
    _getCurrentUser();
    await Future.delayed(const Duration(milliseconds: 1500), () async 
      _getPatients();
    );
    return true;
  

任何帮助将不胜感激!

【问题讨论】:

列表包含哪些元素? 列表包含 1. 图像资产的路径,2. 另一个包含用户信息的自定义模型,最后是一个小部件,如果用户按下 Image.asset,他/她将被导航到那个屏幕 【参考方案1】:

要删除重复项,您可以使用 Set Data Structure 而不是 List。

只需使用 Set 而不是 List 来获取唯一值。

【讨论】:

我执行错了吗?每当我加载具有 FutureBuilder 的屏幕时,它仍然会重复。我将 static List =[]; 更改为 static set myVariable = new LinkedHashSet();以及代码中从 List 到 Set 的所有其他数据类型,但它仍然包含重复项...imgur.com/a/LRg7Q8p 尝试设置 homeList=;集合永远不能包含任何重复值。请在将值添加到设置的 homeList 后通过打印再次打印日志。【参考方案2】:

在添加之前,您可以从模型中删除元素,这将起作用

    dummymodel.removeWhere((m) => m.id == id);
    dummymodel.add(dummymodel.fromJson(data));

【讨论】:

【参考方案3】:

要从数据模型中删除重复项,只需使用 Set(数据结构),

包含重复条目的原始列表:

List<MyDataModel> mList = [MyDataModel(1), MyDataModel(2), MyDataModel(1), MyDataModel(3)];

从您的List&lt;MyDataModel&gt; 中删除重复条目的新列表:

List<MyDataModel> mNewList = list.toSet().toList();

输出: 结果会是这样的

MyDataModel(1)、MyDataModel(2)、MyDataModel(3)

【讨论】:

【参考方案4】:

我想出了一个蛮力的解决方案。而不是

_getPatients() async 
    if (didLoadpatients == 0) 
      print('this is didloadpatients at start of func $didLoadpatients');
      var document = await db
          .collection('users')
          .document(mUser.uid)
          .collection('patients');

      document.getDocuments().then((QuerySnapshot query) async 
        query.documents.forEach((f) 
          uids.add(f.data['uID']);
        );
        didLoadpatients++;
      print('this is didloadpatients at end of func $didLoadpatients');
        for (var i = 0; i < uids.length; i++) 
          var userDocuments = await db.collection('users').document(uids[i]);
          userDocuments.get().then((DocumentSnapshot doc) 
            print(doc.data);
            homeList.add(HomeList(
                imagePath: 'assets/fitness_app/fitness_app.png',
                patientInfo: new PatientInfo.fromFbase(doc.data)));
          );
          print(homeList);
        
      );
     else 
    print('I am leaving the get patient function');
  

我已经按照@Jay Mungara 所说的做,并在每次我的 UI 重建时清除我的 Set:

_getPatients() async 
homeList.clear();
    if (didLoadpatients == 0) 
      print('this is didloadpatients at start of func $didLoadpatients');
      var document = await db
          .collection('users')
          .document(mUser.uid)
          .collection('patients');

      document.getDocuments().then((QuerySnapshot query) async 
        query.documents.forEach((f) 
          uids.add(f.data['uID']);
        );
        didLoadpatients++;
      print('this is didloadpatients at end of func $didLoadpatients');
        for (var i = 0; i < uids.length; i++) 
          var userDocuments = await db.collection('users').document(uids[i]);
          userDocuments.get().then((DocumentSnapshot doc) 
            print(doc.data);
            homeList.add(HomeList(
                imagePath: 'assets/fitness_app/fitness_app.png',
                patientInfo: new PatientInfo.fromFbase(doc.data)));
          );
          print(homeList);
        
      );
     else 
    print('I am leaving the get patient function');
  

感谢您的所有回答!

【讨论】:

【参考方案5】:

要从自定义对象列表中删除重复元素,您需要在 POJO 类中覆盖 == 和 hashcode 方法,然后在 Set 中添加项目并再次将 set 转换为列表以删除重复对象.以下是工作代码:-

class TrackPointList 
double latitude;
double longitude;
String eventName;
Time timeZone;

TrackPointList(
this.latitude,
this.longitude,
this.eventName,
this.timeZone,

);

@override
bool operator==(other) 
// Dart ensures that operator== isn't called with null
// if(other == null) 
//   return false;
// 
if(other is! TrackPointList) 
  return false;

// ignore: test_types_in_equals
return eventName == (other as TrackPointList).eventName;

int _hashCode;
@override
int get hashCode 
if(_hashCode == null) 
  _hashCode = eventName.hashCode;

return _hashCode;

factory TrackPointList.fromJson(Map<String, dynamic> json) => TrackPointList(
latitude: json["latitude"].toDouble(),
longitude: json["longitude"].toDouble(),
eventName: json["eventName"],
timeZone: timeValues.map[json["timeZone"]],

);

Map<String, dynamic> toJson() => 
"latitude": latitude,
"longitude": longitude,
"eventName": eventName,
"timeZone": timeValues.reverse[timeZone],

;

上面是 POJO 类。下面是帮助您根据 eventName 数据成员过滤对象的方法。

List<TrackPointList> getFilteredList(List<TrackPointList> list)

final existing = Set<TrackPointList>();
final unique = list
    .where((trackingPoint) => existing.add(trackingPoint))
    .toList();

return unique;

这肯定会奏效。 如果对您有帮助,请+1。

【讨论】:

以上是关于如何删除 List<MyDataModel> 的重复项(Dart/Flutter)的主要内容,如果未能解决你的问题,请参考以下文章

HashMap和List遍历方法总结及如何遍历删除

如何批量删除list循环出来的值?

c#如对含有二维数据的list如何进行删除操作

如何在连接字符串中包含与号?

Java 如何优雅的在循环中删除元素

Dart/Flutter - 如何删除 List 中 Map 元素的键值对?