Dart

06.Dart基础-内置类型-List

内容纲要

在 Dart 的内置类型中,集合相关的类型共有3个,分别是:

  1. List
  2. Set
  3. Map

其中 List 集合就是其它语言中所谓的数组(Array),在 Dart 中数组用 List 对象表示,本节主要讨论它的基本使用。

1. 声明 List 数组

1.1 基于字面量创建 List

1.1.1 完整形式

基于字面量 <类型>[] 是创建 List 数组最简单的方式。例如,下面的代码创建了一个空数组 arr,用来存储 int 类型的元素:

void main(List<String> args) {
  // 1. 右侧的 <int> 用来指定 [] 中存储的元素的数据类型必须是 int 数字
  // 2. 左侧的 List<int> 表示 arr 变量的类型是 List 数组,数组中元素的类型是 int
  List<int> arr = <int>[];

  // 3. length 属性用来查看数组中元素的个数
  print(arr.length); // 输出 0
  // 4. isEmpty 属性用来判断数组是否为空
  print(arr.isEmpty); // 输出 true
}

1.1.2 类型简写

List<int> arr = <int>[]; 是基于字面量创建数组的完整形式。其中,右侧的 <int> 和左侧的 List<int> 都指定了数组元素的类型,在写法上有些冗余。我们可以按需省略左侧右侧的类型,依然能保证 arrint 类型的数组。示例代码如下:

void main(List<String> args) {
  // List<int> arr = <int>[]; // 完整写法,左侧和右侧都包含类型声明
  // var arr = <int>[];  // 把左边的类型省略,右侧的 <int> 表示 arr 是 int 类型的数组
  // List<int> arr = []; // 把右边的类型省略,左侧的 List<int> 表示 arr 是 int 类型的数组
}

上面的代码简化了定义数组时的类型声明,代码更为简洁,同时还能保证数组中元素的类型,例如向 int 数组中添加其它类型的元素时,代码会报错:

void main(List<String> args) {
  // 1. 声明 int 类型的数组 arr
  var arr = <int>[];

  // 2. 调用数组的 add() 方法,可以向数组中添加元素
  // int 类型的数字 1 可以正常的添加到数组 arr 中,因为元素的类型和数组的类型匹配
  arr.add(1);
  // 3. 字符串 'abc' 无法被添加到数组 arr 中,因为类型不匹配,所以下面这行代码编译会报错
  arr.add('abc');
}

1.1.3 dynamic 数组

注意,如果同时省略了左侧和右侧的类型,则表示声明了一个 dynamic 类型的数组。此时可以向数组中添加不同类型的元素,相当于解除了数组中元素类型必须一致的限制,示例代码如下:

void main(List<String> args) {
  // 1. 完整写法,左侧和右侧都包含类型声明,把 arr 限定为了 int 类型的数组
  // List<int> arr = <int>[];

  // 2. 同时省略两边的类型,表示声明了 dynamic 动态类型的数组,
  // 等同于完整写法的声明方式: List<dynamic> arr = <dynamic>[];
  // 此时可以向数组中存储任意类型的元素
  var arr = [];

  // 3.1 添加数字 1
  arr.add(1);
  // 3.2 添加字符串 'abc'
  arr.add('abc');
  // 3.3 添加布尔值 true
  arr.add(true);

  // 4. 输出 [1, abc, true]
  print(arr);
}

1.1.4 常量数组

在 Dart 中,可以基于 const 声明编译时的常量数组。使用 const 声明的数组是 unmodifiable 的 List,即 “不可修改”的数组。无法删除元素、修改元素、扩充数组长度。示例代码如下:

void main(List<String> args) {
  // 1. 定义可变数组 counts
  List<int?> counts = [1, 2, 3];

  // 1.1 可以修改元素
  counts[0] = 9;
  print(counts); // 输出 [9, 2, 3]

  // 1.2 可以扩充数组(新扩充的元素默认值为 null,因此要把数组类型定义成可为空的 List,即 List<int?> 类型)
  counts.length = 5;
  print(counts); // 输出 [9, 2, 3, null, null]

  // 1.3 可以删除元素
  counts.removeAt(0);
  print(counts); // 输出 [2, 3, null, null]

  // ----

  // 2. 定义常量数组 ages,下面的代码等同于 const List<int> ages = [22, 28, 19];
  List<int> ages = const [22, 28, 19];

  // 2.1 修改元素的值,报错:Cannot modify an unmodifiable list
  ages[0] = 31;

  // 2.2 扩充数组,报错:Cannot change the length of an unmodifiable list
  ages.length = 5;

  // 2.3 删除元素,报错:Cannot remove from an unmodifiable list
  ages.removeAt(0);
}

注意:在定义常量数组时,关键字 const 可以放在字面量数组之前,也可以放在变量类型之前,以下代码是等价的:

const List ages = [1, 2, 3];

List ages = const [1, 2, 3];

1.2 基于构造函数创建 List

1.2.1 List.empty()

基于 List.empty({bool growable = false}); 构造函数可以创建一个空数组。其中可选参数 growable 的默认值为 false,表示创建的空数组长度固定为 0,不允许向数组中添加任何新元素,示例代码如下:

void main(List<String> args) {
  // 1. 基于 empty 构造函数,创建空数组,
  // growable 的默认值为 false,表示空数组的长度固定为 0,不允许向数组中添加任何元素
  List arr1 = List.empty();

  print(arr1.length); // 输出 0

  // 报错 Cannot add to a fixed-length list
  // 无法向固定长度的数组中添加元素
  arr1.add(1);
}

为了创建可增长的空数组,可以在调用 empty() 构造函数时把 growable 选项设置为 true。示例代码如下:

void main(List<String> args) {
  // 把 growable 设置为 true
  List arr1 = List.empty(growable: true);
  print(arr1.length); // 输出 0

  // 可以正常添加元素
  arr1.add('abc');

  print(arr1); // 输出 [abc]
  print(arr1.length); // 输出 1
}

1.2.2 List.filled()

基于 List.filled(int length, E fill, {bool growable = false}); 构造函数,可以创建指定长度的数组,并以给定的内容作为每个元素的初值进行填充。其中第三个参数 growable 的默认值为 false,表示创建的是长度固定的数组。示例代码如下:

void main(List<String> args) {
  // 创建长度为 3 的数组,并把每个元素的初始值填充为数字 0
  List<int> arr2 = List.filled(3, 0);
  // 输出 [0, 0, 0]
  print(arr2);

  // 把索引为 0 的元素赋值为 9
  // 注意:固定长度的数组指元素的个数不能增加也不能减少,但是不影响修改现有元素的值
  arr2[0] = 9;
  // 输出 [9, 0, 0]
  print(arr2);

  // 报错 Cannot add to a fixed-length list
  // 无法向固定长度的数组中添加元素
  // arr2.add(9);

  // 报错 Cannot change the length of a fixed-length list
  // 无法修改固定长度的数组的 length
  // arr2.length = 1;
}

可以显示指定 growable true 从而创建可增长的数组。示例代码如下:

void main(List<String> args) {
  // 创建初始长度为 3 的数组,并把每个元素的初始值填充为数字 0
  List<int?> arr2 = List.filled(3, 0, growable: true);
  // 输出 [0, 0, 0]
  print(arr2);

  // 向数组中添加元素 9
  arr2.add(9);
  // 输出 [0, 0, 0, 9]
  print(arr2);

  // 修改数组的 length 为 1,会删除多余的元素
  arr2.length = 1;
  // 输出 [0]
  print(arr2);

  // 扩充数组的 length 为 5,新扩充的元素值会被填充为 null
  // 注意:声明数组时必须使用 List<int?> 把数组元素声明成可为 null 的元素,否则扩充会报错
  arr2.length = 5;
  // 输出 [0, null, null, null, null]
  print(arr2);
}

1.2.3 List.unmodifiable()

基于 List.unmodifiable(Iterable elements); 构造函数,可以创建不可修改的数组。示例代码如下:

void main(List<String> args) {
  // 1. 定义普通数组
  var arr1 = <int>[1, 2, 3];
  // 3. 调用 unmodifiable 构造函数,基于 arr1 创建出不可修改的数组 arr2
  var arr2 = List.unmodifiable(arr1);

  // 3. 报错 Cannot change the length of an unmodifiable list
  // 不允许修改数组的 length
  // arr2.length = 1;

  // 4. 报错 Cannot modify an unmodifiable list
  // 不允许修改数组中元素的值
  // arr2[0] = 9;
}

注意:growable 为 false 的数组,不允许添加和删除元素,但是允许修改现有元素的值。而 unmodifiable 的数组既不允许添加和删除元素,又不允许修改现有元素的值。

2. 操作 List 元素

2.1 添加元素

2.1.1 添加单个元素

调用数组的 add 方法可以向数组中添加单个元素,示例代码如下:

void main(List<String> args) {
  // 定义数组(可增长)
  List<String> names = [];

  // add 方法一次只能添加 1 个元素
  names.add('zs');
  names.add('ls');

  // 输出 [zs, ls]
  print(names);
}

2.1.2 添加多个元素

调用数组的 addAll 方法可以向数组中一次性添加多个元素,示例代码如下:

void main(List<String> args) {
  // 定义数组
  List<int> arr = [1, 2];
  // 一次性添加多个元素
  arr.addAll([3, 4, 5]);
  // 输出 [1, 2, 3, 4, 5]
  print(arr);
}

2.2 移除元素

2.2.1 remove()

数组的 remove 方法用来移除指定的元素,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'A'];
  // 移除指定的元素,如果移除成功,则返回 true,否则返回失败
  // 如果存在多个相同的元素,则只移除最左侧的那个元素
  bool result = arr.remove('A');

  print(result); // 输出 true
  print(arr); // 输出 [B, C, D, E, F, A]

  bool result2 = arr.remove('Z');
  print(result2); // 输出 false,因为数组中不存在元素 'Z'
}

2.2.2 removeLast()

数组的 removeLast 方法用来从末尾移除元素,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = ['A', 'B', 'C', 'D', 'E', 'F'];
  // 移除数组末尾的元素,并返回这个被移除的元素
  var result = arr.removeLast();

  print(result); // 输出 F
  print(arr); // 输出 [A, B, C, D, E]
}

注意:在空数组上调用 removeLast 方法会报错。

2.2.3 removeAt()

数组的 removeAt 方法用来根据索引移除元素,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = ['A', 'B', 'C', 'D', 'E', 'F'];
  // 移除指定索引的元素,并返回这个被移除的元素
  var result = arr.removeAt(1);

  print(result); // 输出 B
  print(arr); // 输出 [A, C, D, E, F]
}

注意:如果提供的索引小于 0 或大于 length-1,则会报错。

2.2.4 removeRange()

数组的 removeRange(int start, int end) 方法用来根据索引范围移除区间内的元素,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = ['A', 'B', 'C', 'D', 'E', 'F'];
  // 根据起始索引和结束索引,移除范围内的元素
  // 注意:包前不包后,移除的范围是索引为 start 到索引为 end-1 的元素
  arr.removeRange(0, 2);

  print(arr); // 输出 [C, D, E, F]
}

注意:start 和 end 的取值范围是 0 到 length,而且 start 必须小于 end。

2.2.5 removeWhere()

数组的 removeWhere 方法可以根据筛选条件移除指定的元素,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = [1, 2, 3, 4, 5, 6];
  // 根据条件移除元素,所有满足 where 条件的元素都会被移除掉
  // 移除所有偶数
  arr.removeWhere((element) => element % 2 == 0);

  print(arr); // 输出 [1, 3, 5]
}

2.2.6 使用索引清空数组

可以把数组的 length 赋值为 0,从而实现清空数组的功能,示例代码如下:

void main(List<String> args) {
  // 声明数组
  var arr = [1, 2, 3, 4, 5, 6];

  // 把数组的 length 赋值为 0
  names.length = 0;
  // 输出 true,证明是空数组
  print(names.isEmpty);
}

2.3 插入元素

2.3.1 insert()

数组的insert(index, element) 方法可以向指定的索引位置插入单个元素,示例代码如下:

void main(List<String> args) {
  var names = ['嬴政', '小乔', '蔡文姬'];
  // 在索引为 1 的位置插入指定的元素
  names.insert(1, '甄姬');
  // 输出 [嬴政, 甄姬, 小乔, 蔡文姬]
  print(names);
}

注意:在提供插入的索引时,索引的取值范围是 0 到 length,否则会报错。

2.3.2 insertAll()

数组的 insertAll(index, elements) 方法可以向指定的索引位置插入多个元素,示例代码如下:

void main(List<String> args) {
  var names = ['嬴政', '小乔', '蔡文姬'];
  // 在索引为 2 的位置插入指定的元素
  names.insertAll(2, ['甄姬', '虞姬', '香香']);
  // 输出 [嬴政, 小乔, 甄姬, 虞姬, 香香, 蔡文姬]
  print(names);
}

注意:在提供插入的索引时,索引的取值范围是 0 到 length,否则会报错。

3. List 常用方法

3.1 查找元素的索引

3.1.1 indexOf

数组的 indexOf 方法用来查找匹配元素的索引,如果存在多个匹配的元素,只返回第一个匹配项的索引值,如果没有匹配的元素则返回 -1。示例代码如下:

void main(List<String> args) {
  var names = ['嬴政', '小乔', '蔡文姬', '小乔'];
  var index = names.indexOf('小乔');
  print(index); // 找到了,输出 1

  var index2 = names.indexOf('大乔');
  print(index2); // 没找到,输出 -1
}

3.1.2 lastIndexOf

数组的 lastIndexOf 方法用来查找最后一个匹配项的索引值,如果没有匹配的元素,则返回 -1。示例代码如下:

void main(List<String> args) {
  var names = ['嬴政', '小乔', '蔡文姬', '小乔'];

  var index3 = names.lastIndexOf('小乔');
  print(index3); // 找到了,输出索引 3

  var index4 = names.lastIndexOf('大乔');
  print(index4); // 没找到,输出 -1
}

3.1.3 根据 where 条件查询匹配项的索引

数组的 indexWhere 用来从左侧进行条件查找,lastIndexWhere 用来从右侧进行条件查找,示例代码如下:

void main(List<String> args) {
  var names = ['嬴政', '小乔', '蔡文姬', '小乔'];

  // 查找元素 length == 3 的元素的索引
  var index5 = names.indexWhere((element) => element.length == 3);
  print(index5); // 输出索引 2

  // 从右侧查找元素中包含 '乔' 的元素的索引
  var index6 = names.lastIndexWhere((element) => element.contains('乔'));
  print(index6); // 输出索引 3
}

3.2 替换区间元素

3.2.1 fillRange

调用数组的 fillRange(int start, int end, [E? fillValue]); 方法可以把指定区间的元素填充(覆盖)为指定的值。填充的范围是 ≥start 索引,<end 索引。示例代码如下:

void main(List<String> args) {
  // 1. 定义可为空的 int 数组
  List<int?> nums = [1, 2, 3];
  // 2. 扩充数组长度到 10
  nums.length = 10;
  // 3. 输出 [1, 2, 3, null, null, null, null, null, null, null],后 7 个元素默认值为 null
  print(nums);

  // 4. 把索引 ≥3 到索引<10 的元素值覆盖为数字 0
  // 注意:索引包前不包后
  nums.fillRange(3, nums.length, 0);
  // 5. 输出 [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
  print(nums);
}

3.2.2 replaceRange

调用数组的 replaceRange(int start, int end, Iterable<E> replacements); 方法可以把指定区间的元素整体替换为指定的元素。替换的范围是 ≥start 索引,<end 索引。示例代码如下:

void main(List<String> args) {
  // 1. 基于 List.filled() 构造函数,初始化 length 为 10 的可增长数组,并把每项的初值填充为数字 0
  List<int> counts = List.filled(10, 0, growable: true);
  // 2. 输出 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  print(counts);

  // 3. 把索引 ≥3 到索引 <8 的元素,整体替换为元素 1 和 元素 2
  // 相当于把索引 3-7 的元素移除,再把指定的元素插入到索引为 3 的位置
  counts.replaceRange(3, 8, [1, 2]);
  // 4. 输出 [0, 0, 0, 1, 2, 0, 0]
  print(counts);
}

3.2.3 setRange

调用数组的 setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]); 方法可以把指定区间的元素替换为另一个数组中的元素。替换的范围是 ≥start 索引,<end 索引。示例代码如下:

void main(List<String> args) {
  // 1. 定义动态元素类型的数组 arr
  var arr = <dynamic>[1, 2, 3, 4, 5];
  // 2. 定义字符数组 characters
  var characters = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];

  // 3. 把 arr 数组索引 ≥1 到索引<4 的三个元素(2,3,4)替换为新值,
  // 新值从数组 characters 中提取,默认从索引为 0 的位置往后提取,提取的个数为 end - start
  // 最终结果:从 characters 数组中提取三个元素 A, B, C,并把这三个元素填充到数组 arr 中,从索引为 1 的位置往后填充
  arr.setRange(1, arr.length - 1, characters);
  // 输出 [1, A, B, C, 5]
  print(arr);
}

在进行元素提取时,可以提供 skipCount 选项来指定从索引为几的位置开始提取,但一定要保证能提取的元素数量满足 end - start,否则会报错。示例代码如下:

void main(List<String> args) {
  // 1. 定义动态元素类型的数组 arr
  var arr = <dynamic>[1, 2, 3, 4, 5];
  // 2. 定义字符数组 characters
  var characters = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];

  // 3. 把 arr 数组索引 ≥1 到索引<4 的三个元素(2,3,4)替换为新值,
  // 新值从数组 characters 中提取,默认从索引为 4 的位置往后提取,提取的个数为 end - start
  // 最终结果:从 characters 数组中提取三个元素 E, F, G,并把这三个元素填充到数组 arr 中,从索引为 1 的位置往后填充
  arr.setRange(1, arr.length - 1, characters, 4);
  // 输出 [1, E, F, G, 5]
  print(arr);
}

3.3 排序与乱序

调用数组的 shuffle 方法可以随机打乱数组中元素的顺序,调用数组的 sort 方法可以进行排序。示例代码如下:

void main(List<String> args) {
  // 1. 定义数组
  var counts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  // 2. 调用 shuffle 方法随机打乱数组
  counts.shuffle();
  // 3. 输出打乱的结果为 [4, 8, 9, 5, 2, 10, 6, 7, 3, 1] 或其它随机的结果
  print(counts);

  // 4. 直接调用 sort() 方法进行排序时,默认是升序排序
  // 如果提供了比较函数,当 a - b 时进行升序排序
  // 如果提供了比较函数,当 b - a 时进行降序排序
  // 注意:比较函数的返回值必须是数字
  counts.sort((a, b) => b - a);

  // 5. 输出 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
  print(counts);
}

如果要为字符串的数组调用 sort 进行排序,可以在比较函数中使用字符串的 compareTo 方法,返回一个数字供 sort 方法进行排序。示例代码如下:

void main(List<String> args) {
  // 1. 定义字符串的数组
  var strs = ['I', 'C', 'U', 'AF', 'D', 'AR', 'A'];

  // 2. 直接调用 sort() 方法进行排序时,默认是升序排序
  // 如果提供了比较函数,当 a.compareTo(b) 时进行升序排序
  // 如果提供了比较函数,当 b.compareTo(a) 时进行降序排序
  strs.sort((a, b) => b.compareTo(a));

  // 3. 输出 [U, I, D, C, AR, AF, A]
  print(strs);
}

3.4 反转数组

反转数组使用的是 reversed 属性,它会返回一个可迭代的集合,再调用 toList 方法可以得到一个反转后的新数组。示例代码如下:

void main(List<String> args) {
  // 1. 定义原数组
  var arr = [1, 2, 3, 4, 5];
  // 2. 通过数组的 reversed 属性得到一个可迭代的集合
  var newArr = arr.reversed;
  // 3. 调用可迭代集合的 .toList() 方法可以把它转为数组
  // 输出 [5, 4, 3, 2, 1]
  print(newArr.toList());
}

3.5 拼接元素

join 方法会根据指定的字符串把数组中的每个元素拼接在一起,最终返回拼接好的字符串,示例代码如下:

void main(List<String> args) {
  // 定义数组 colors
  var colors = <String>['red', 'blue', 'cyan', 'orange'];

  // 根据指定的字符串拼接 Set 中的每个元素
  var result = colors.join(', ');
  // 输出字符串 red, blue, cyan, orange
  print(result);
}

4. 其它操作

4.1 扩展操作符

Dart 在 2.3 引入了 扩展操作符...),它可以方便地合并多个集合。示例代码如下:

void main(List<String> args) {
  // 1. 定义数组 arr1,包含三个数字元素
  var arr1 = [1, 2, 3];

  // 2. 定义数组 arr2,并把 arr1 中的每个元素展开,插入到元素 0 和元素 4 之间
  var arr2 = [0, ...arr1, 4];

  // 3. 输出 [0, 1, 2, 3, 4]
  print(arr2);
}

4.2 空感知扩展操作符

Dart 在 2.3 还引入了空感知扩展操作符...?),如果扩展操作符右边可能为 null,可以避免产生异常:

void main(List<String> args) {
  // 1. 定义变量 arr1 的值为 null
  var arr1 = null;
  // 2. 使用“空感知扩展操作符”进行集合的合并
  var arr2 = [0, ...?arr1];
  // 3. 输出 [0]
  print(arr2);
}

4.3 集合中的 if

在集合中使用三元运算时,必须为 true 和 false 提供对应的值。但在有些情况下,我们只想提供条件成立时候的值,这个时候三元运算符就不满足我们的需求了,例如:

void main(List<String> args) {
  var age = 16;

  // 如果年龄 ≥18 岁,则往数组中添加元素 '饮酒'
  // 如果年龄 <18 岁,则不往数组中添加任何元素
  // 很明显,使用三元运算无法满足我们的要求,因为它总是要求我们提供两个值
  var hobby = ['吃饭', '睡觉', age >= 18 ? '饮酒' : ''];

  print(hobby.length); // 输出 3
}

为了实现上述的需求“如果年龄 <18 岁,则不往数组中添加任何元素”,我们能想到的办法就是结合 if 判断,按需往数组中添加元素。示例代码如下:

void main(List<String> args) {
  var age = 16;

  // 如果年龄 ≥18 岁,则往数组中添加元素 '饮酒'
  // 如果年龄 <18 岁,则不往数组中添加任何元素
  var hobby = ['吃饭', '睡觉'];

  // 使用 if 判断,只有条件成立,才向数组中添加元素
  if (age >= 18) {
    hobby.add('饮酒');
  }

  print(hobby.length); // 输出 2
  print(hobby); // 输出 [吃饭, 睡觉]
}

结合 if 判断动态往数组中添加元素是个好办法,但是在代码写法上比较繁琐。因此,Dart 提供了新语法“在集合中使用 if”。上面的代码可以简写成为如下的方式:

void main(List<String> args) {
  var age = 16;

  // 如果年龄 ≥18 岁,则往数组中添加元素 '饮酒'
  // 如果年龄 <18 岁,则不往数组中添加任何元素
  // 在集合中使用 if 判断,如果条件成立,则向数组中添加元素 '饮酒',否则不添加任何元素
  var hobby = ['吃饭', '睡觉', if (age >= 18) '饮酒'];

  print(hobby.length); // 输出 2
  print(hobby); // 输出 [吃饭, 睡觉]
}

另外,集合中的 if 还能与 else ifelse 配合使用,从而实现更复杂的条件判断:

void main(List<String> args) {
  var flag = 'XXX';

  var arr = [
    'hello',
    'world',
    // 如果 flag 的值是 'ok',则向数组中插入字符串 '成功'
    // 如果 flag 的值是 'no',则向数组中插入字符串 '失败'
    // 否则,向数组中插入字符串 '未知'
    if (flag == 'ok') '成功' else if (flag == 'no') '失败' else '未知'
  ];

  // 输出 [hello, world, 未知]
  print(arr);
}

4.4 集合中的 for

集合中的 for 循环,能帮助我们更快地初始化集合中元素的值。例如:创建一个包含 1 - 10 数字的数组,用集合中的 for 循环可以更方便的实现需求。代码如下:

void main(List<String> args) {
  // 1. 定义空数组
  var nums = [];

  // 2. 循环 10 次,把每次循环时的 i 添加到数组中
  for (var i = 1; i <= 10; i++) {
    nums.add(i);
  }

  // 3. 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  print(nums);

  // ----

  // 1. 在集合内使用 for 循环,把变量 i 的值作为每个元素的值插入到数组中
  var newNums = [for (var i = 1; i <= 10; i++) i];
  // 2. 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  print(newNums);
}

同时,集合中的 for 还能结合集合中的 if 一起使用。示例代码如下:

// 导入 math 库,才可以使用 pow() 函数
import 'dart:math';

void main(List<String> args) {
  // 1. 定义数组 nums
  var nums = [11, 22, 33, 44, 55, 66, 77];

  // 2. 循环数组中的每一项,如果是偶数,则求平方;如果是奇数,则求立方
  // 最终把新值存储数组 newNums 中
  var newNums = [
    for (var i = 0; i < nums.length; i++)
      if (nums[i] % 2 == 0) pow(nums[i], 2) else pow(nums[i], 3)
  ];

  // 3. 输出 [1331, 484, 35937, 1936, 166375, 4356, 456533]
  print(newNums);
}

注意:上面的示例只是从代码层面做了演示,实际开发中还要根据业务场景来决定是否使用它们。

关于 List 集合的更多用法,请参考 List 的官方文档

一个不再讲课の前端程序员。

2条评论

留言

您的电子邮箱地址不会被公开。 必填项已用*标注