ZetCode

Dart 过滤 List

最后修改于 2025 年 6 月 8 日

在本文中,我们将探讨 Dart 中过滤 List 元素的各种技术。过滤是编程中的一项基本操作,它允许开发人员高效地从集合中提取相关数据。

过滤是指根据给定条件从数据结构(例如列表或数组)中选择特定元素的过程。结果是一个新的数据结构,其中仅包含满足条件的元素,而其他元素则被排除。

在 Dart 中,过滤通常使用可迭代对象和内置方法(如 where)来执行。过滤条件使用谓词函数定义,谓词函数是一个接受元素作为输入并返回布尔值(指示是否应包含该元素)的函数。

谓词是一个评估集合中每个元素并返回 true 或 false 的函数。谓词返回 true 的元素将包含在过滤结果中,而其他元素将被丢弃。

过滤在各种应用程序中被广泛使用,包括:

通过利用 Dart 的内置过滤方法,开发人员可以有效地操作集合,同时保持代码的简洁性和可读性。

使用 where 过滤 Dart List

where 函数返回所有满足谓词函数的元素。

main.dart
void main() {
  var vals = <int>[-1, 3, 2, 0, 1, -3, 4, 3, 5];
  var positive = vals.where((e) => e > 0);
  print(positive);

  var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
  var w3 = words.where((e) => e.length == 3);
  print(w3);
}

在示例中,我们过滤了两个列表。

var vals = <int>[-1, 3, 2, 0, 1, -3, 4, 3, 5];
var positive = vals.where((e) => e > 0);

我们过滤掉所有正数。我们将一个匿名函数传递给 where 函数。

var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
var w3 = words.where((e) => e.length == 3);

在这里,我们获取所有长度为 3 的单词。

$ dart main.dart 
(3, 2, 1, 4, 3, 5)
(sky, oak)

使用 retainWhere 过滤 Dart List

retainWhere 函数会从列表中删除所有未能满足给定谓词的元素。

main.dart
void main() {

  var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
  var words2 = List<String>.of(words);

  words2.retainWhere((e) => e.startsWith("w"));

  print(words);
  print(words2);
}

在程序中,我们想获取所有以“w”开头的单词。

var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
var words2 = List<String>.of(words);

首先,我们创建原始列表的副本。

words2.retainWhere((e) => e.startsWith("w"));

我们将 retainWhere 函数应用于列表。它接受一个匿名谓词,该谓词使用 startsWith 检查元素是否以“w”开头。

$ dart main.dart 
[wolf, sky, falcon, cloud, wood, oak]
[wolf, wood]

Dart removeWhere

removeWhere 会从列表中删除所有满足给定谓词的元素。

main.dart
void main() {
  var words = <String?>["wolf", null, "falcon", null, "cloud", "wood", "oak"];

  words.removeWhere((e) => e == null);
  print(words); 
}

我们从单词列表中删除所有 null 值。

$ dart main.dart 
[wolf, falcon, cloud, wood, oak]

过滤 Dart 对象 List

在下一个示例中,我们过滤对象列表。

main.dart
class Employee {
  String fname;
  String lname;
  int salary;

  Employee(this.fname, this.lname, this.salary);

  @override
  String toString() {
    return "$fname $lname: $salary";
  }
}

void main() {
  var empls = <Employee>[
    new Employee("John", "Doe", 1230),
    new Employee("Adam", "Novak", 670),
    new Employee("Robin", "Brown", 2300),
    new Employee("Rowan", "Cruise", 990),
    new Employee("Joe", "Draker", 1190),
    new Employee("Janet", "Doe", 980),
    new Employee("Lucy", "Smith", 980),
    new Employee("Thomas", "Moore", 1400)
  ];

  var filtered = empls.where((e) => e.salary > 1000);
  print(filtered);
}

我们有一个员工列表。我们想要所有工资高于 1000 的员工。

var filtered = empls.where((e) => e.salary > 1000);

在谓词中,我们访问元素的 salary 属性并将其与 1000 进行比较。

$ dart main.dart 
(John Doe: 1230, Robin Brown: 2300, Joe Draker: 1190, Thomas Moore: 1400)

Dart whereType

使用 whereType 函数,我们可以获取给定类型的所有值。

main.dart
void main() {
  var data = ['sky', 2, 'owl', 11, 'forest', 'falcon'];

  var words = data.whereType<String>();
  print(words);
}

在示例中,我们从 data 列表中过滤掉所有单词。

$ dart main.dart 
(sky, owl, forest, falcon)

使用 List comprehension (列表推导)

列表推导是一种语法结构,它根据现有列表和过滤条件创建列表。

main.dart
void main() {
  var vals = <int>[-1, 3, 2, 0, 1, -3, 4, 3, 5];

  var negative = [
    for (var e in vals)
      if (e < 0) e
  ];

  print(negative);
}

使用列表推导,我们创建一个只包含负值的新列表。

$ dart main.dart 
[-1, -3]

使用索引过滤 Dart List

有时您可能希望根据元素值及其索引来过滤列表。您可以通过使用 asMapList.generate 来实现这一点。

main.dart
void main() {
  var vals = <int>[10, 15, 20, 25, 30, 35, 40];

  // Keep only even-indexed elements that are greater than 20
  var filtered = vals.asMap().entries
      .where((entry) => entry.key % 2 == 0 && entry.value > 20)
      .map((entry) => entry.value);

  print(filtered.toList());
}

在此示例中,我们只保留索引为偶数且值大于 20 的元素。

$ dart main.dart
[30, 40]

链式过滤

您可以链接多个 where 调用,以按顺序应用多个过滤条件。

main.dart
void main() {
  var vals = <int>[3, 6, 9, 12, 15, 18, 21, 24, 27, 30];

  // Keep only numbers greater than 10 and divisible by 3
  var filtered = vals.where((e) => e > 10).where((e) => e % 3 == 0);

  print(filtered.toList());
}

在这里,我们首先过滤出大于 10 的数字,然后只保留那些能被 3 整除的数字。

$ dart main.dart
[12, 15, 18, 21, 24, 27, 30]

来源

Dart List - 语言参考

在本文中,我们探讨了 Dart 中过滤列表的各种技术。我们介绍了 where 方法的使用,该方法允许我们根据谓词函数过滤元素。我们还讨论了 retainWhereremoveWhere 方法,它们通过保留或删除满足给定条件的元素来修改原始列表。此外,我们研究了使用列表推导进行过滤,并演示了如何根据对象的属性过滤对象列表。最后,我们探索了高级过滤技术,例如使用索引进行过滤和链接多个过滤器。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 Dart 教程