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

我有一个基于列表构建 UI 的 futurebuilder,它完成了这项工作,但是由于每次导航时都会一次又一次地构建 UI,因此我得到了重复。我的问题是,Dart 中是否有一种先天方法可以从列表中删除重复项?我试过这个StackOverflow 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,他/她将被导航到那个屏幕

标签: list flutter dart


【解决方案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。

        【讨论】:

          猜你喜欢
          • 2021-02-25
          • 2015-12-29
          • 2014-10-04
          • 2011-04-19
          • 2015-05-23
          • 1970-01-01
          • 1970-01-01
          • 2021-12-10
          • 1970-01-01
          相关资源
          最近更新 更多