如何区分 DART 中的复杂对象列表

Kat*_*kko 4 list distinct dart flutter

我有一个复杂对象的列表。如何使用 ID 区分列表?

我不能使用 toSet 和类似的东西,因为所有对象的哈希码都不同。

Abi*_*n47 13

1) 香草飞镖

循环浏览列表,随时将 ID 添加到集合中。每当您向集合中添加尚不存在的 ID 时,请将该元素添加到新的不同值列表中。

void main() {
  var list = [
    Data('a'),
    Data('a'),
    Data('b'),
    Data('c'),
  ];
  
  var idSet = <String>{};
  var distinct = <Data>[];
  for (var d in list) {
    if (idSet.add(d.id)) {
      distinct.add(d);
    }
  }
}

class Data {
  Data(this.id);
  final String id;
}
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是直接创建一个实例HashSet(或者LinkedHashSet如果您关心插入顺序)并手动指定将用于确定唯一性的相等操作。

(此方法可能比第一个选项更高效,因为所有项目都是一次性添加的,而不是循环遍历列表并单独添加每个项目。但是,这取决于每个目标平台上类的本机实现,因此在实践中它可能不会表现得更好。)

import 'dart:collection';

void main() {
  final list = [
    Data('a'),
    Data('a'),
    Data('b'),
    Data('c'),
  ];

  final dataSet = HashSet<Data>( // or LinkedHashSet
    equals: (a, b) => a.id == b.id,
    hashCode: (a) => a.id.hashCode,
  )..addAll(list);
}

class Data {
  Data(this.id);
  final String id;
}
Run Code Online (Sandbox Code Playgroud)

2) 套餐

存在几个扩展默认Iterable实用程序方法的包,例如flinqdarq。他们添加了一个distinct方法,您可以调用该方法来根据成员的某些属性轻松获取列表中唯一成员的列表。

import 'package:darq/darq.dart';

void main() {
  var list = [
    Data('a'),
    Data('a'),
    Data('b'),
    Data('c'),
  ];
  var distinct = list.distinct((d) => d.id).toList();
}
Run Code Online (Sandbox Code Playgroud)

(免责声明,我是 darq 的维护者。)


And*_*her 11

尝试使用这个扩展(使用 Abion47 的评论进行了改进):

extension IterableExtension<T> on List<T> {
  Iterable<T> distinctBy(Object getCompareValue(T e)) {
    var idSet = <Object>{};
    var distinct = <T>[];
    for (var d in this) {
      if (idSet.add(getCompareValue(d))) {
        distinct.add(d);
      }
    }

    return distinct;
  }
}
Run Code Online (Sandbox Code Playgroud)

使用:

var distinctList = someList.distinctBy((x) => x.oid);
Run Code Online (Sandbox Code Playgroud)

或者你可以在那里使用哈希。