【Dart 教程系列第 4 篇】Dart 中 List 数组的常用方法

5,176 阅读14分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

这是【Dart 教程系列第 4 篇】,如果觉得有用的话,欢迎关注专栏。

Dart 中 List 数组的方法还是比较多的,这里我按照 CRUD 对这些方法进行分类汇总。

其中 CRUD 指的是增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。

一:"增加"数据的方法(4 个)

add 添加一个元素到数组末尾 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.add("周四");
  l1.add("周五");
  print(l1); // [周一, 周二, 周三, 周四, 周五]

addAll 合并两个数组 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  List<String> l2 = ["周四", "周五", "周六","周日"];
  l1.addAll(l2);
  print(l1); // [周一, 周二, 周三, 周四, 周五, 周六, 周日]

insert 在指定索引处插入一个值 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.insert(3, "周四");
  print(l1); // [周一, 周二, 周三, 周四]
  l1.insert(0, "周日");
  print(l1); // [周日, 周一, 周二, 周三, 周四]

insertAll 在指定索引处插入一个数组 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  List<String> l2 = ["周四", "周五", "周六", "周日"];
  l1.insertAll(0, l2);
  print(l1); // [周四, 周五, 周六, 周日, 周一, 周二, 周三]

二:"删除"数据的方法(6 个)

remove 删除指定元素 查看更多

  List<String> l1 = ["周一", "周二", "周三","周一"];
  l1.remove("周一");
  print(l1); // [周二, 周三, 周一]

removeAt 删除指定索引位置处的元素 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.removeAt(0);
  print(l1); // [周二, 周三]

removeLast 删除数组的最后一个元素 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.removeLast();
  print(l1); // [周一, 周二]

clear 清空数组 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.clear();
  print(l1); // []

removeWhere 根据指定条件删除元素 查看更多

  List<String> l1 = ["周一", "周二", "周三"];
  l1.removeWhere((e) => e == "周二");
  print(l1); // [周一, 周三]
  
  List<String> l2 = ["周一", "周二", "周三","星期四"];
  l2.removeWhere((e) => e.contains("周"));
  print(l2); // [星期四]

关于以上删除元素的方法

  • 如果数组中有该数据或者满足删除的条件,则删除,原数组发生改动。
  • 如果要删除的数据不在数组中,或者删除元素的条件不成立,也不会报错,返回原数组。

removeRange 删除指定索引范围内的元素(含头不含尾) 查看更多

  List<String> l1 = ["周一", "周二", "周三","周四", "周五", "周六", "周日"];
  l1.removeRange(2, 5);
  print(l1); // [周一, 周二, 周六, 周日]

三:"修改"数据的方法(5 个)

List [index] 修改指定索引位置元素的值

  List<String> l1 = ["周一", "周二", "周三", "星期四"];
  l1[3] = "周四";
  print(l1); // [周一, 周二, 周三, 周四]

fillRange 用相同的值替换指定索引范围内的所有元素(含头不含尾)

  List<String> l1 = ["周一", "周二", "周三", "周四", "周五"];
  l1.fillRange(1, 4, "AllenSu");
  print(l1); // [周一, AllenSu, AllenSu, AllenSu, 周五]

replaceRange 用某一数组替换指定索引范围内的所有元素(含头不含尾)

  List<String> l1 = ["周一", "周二", "周三"];
  l1.replaceRange(1, 2, ["周四", "周五", "周六", "周日"]);
  print(l1); // [周一, 周四, 周五, 周六, 周日, 周三]
  
  List<String> l2 = ["周一", "周二", "周三", "周四", "周五"];
  l2.replaceRange(0, 4, ["周六", "周日"]);
  print(l2); // [周六, 周日, 周五]

setRange 范围替换数组中的值(含头不含尾)

  List<String> l1 = ["11", "22", "33"];
  List<String> l2 = ["aa", "bb", "cc"];
  l1.setRange(0, 2, l2); // 用 l2 数组中索引为 0 1 位置处元素的值,替换掉 l1 数组中索引 0 1 位置处元素的值
  print(l1); // [aa, bb, 33]

setAll 从指定索引位置开始,使用第二个数组内的元素依次替换掉第一个数组中的元素

  List<String> l1 = ["周一", "周二", "周三", "周四"];
  List<String> l2 = ["周五", "周六", "周日"];
  l1.setAll(1, l2);
  print(l1); // [周一, 周五, 周六, 周日]

注意: index + l2.length <= l1.length ,否则会报错。

四:"查询"数据的方法(20 个)

elementAt 获取指定索引位置处的元素 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四"];
  String str = l1.elementAt(2);
  print(str); // 周三

contains 判断数组中是否含有指定元素 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四"];
  bool a = l1.contains("周一");
  bool b = l1.contains("周日");
  print(a); // true
  print(b); // false

indexOf 获取指定元素在数组中的索引 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
  int a = l1.indexOf("周三"); // 获取数组中第一次出现"周三"元素的索引
  int b = l1.indexOf("周三", 3); // 从索引为3开始,查找第一次出现"周三"元素的索引
  int c = l1.indexOf("周日");
  print(a); // 2
  print(b); // 4
  print(c); // -1,数组中不存在指定元素,返回 -1

lastIndexOf 从后向前查找指定元素在数组中的索引 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
  int a = l1.lastIndexOf("周三");
  int b = l1.lastIndexOf("周三", 3);
  int c = l1.lastIndexOf("周日");
  print(a); // 4
  print(b); // 2
  print(c); // -1

indexWhere 返回第一个满足条件的元素的索引 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
  int a = l1.indexWhere((e) => e == "周三");
  print(a); // 2

lastIndexWhere 从后向前找,返回第一个满足条件的元素的索引 查看更多

  List<String> l1 = ["周一", "周二", "周三", "周四", "周三"];
  int a = l1.lastIndexWhere((e) => e == "周三");
  print(a); // 4

where 根据指定条件,函数筛选每个元素,符合条件的元素组成一个新的 Iterable 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.where((e) => e > 10);
  print(l2); // (12, 17, 33)
  
  List<int> l3 = l1.where((e) => e >= 10).toList();
  print(l3); // [12, 17, 33]

firstWhere 返回第一个满足条件的元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  int a = l1.firstWhere((e) => e > 10);
  print(a); // 12

lastWhere 从后向前查找第一个满足条件的元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  int a = l1.lastWhere((e) => e > 10);
  print(a); // 33

singleWhere 获取满足指定条件的唯一元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  int a = l1.singleWhere((e) => e > 30);
  int b = l1.singleWhere((e) => e > 33, orElse: () => -1);
  int c = l1.singleWhere((e) => e > 10, orElse: () => null);
  print(a); // 33
  print(b); // -1。数组中没有满足条件的元素,返回 orElse 方法指定的返回值(-1是自己填的,你也可以设置为其它值)
  print(c); // 报错。当数组中有多个满足条件的元素时,即使你设置了 orElse 的返回值,用 singleWhere 也会报错

retainWhere 保留满足条件的元素(改变了原数组) 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  l1.retainWhere((e) => e > 10);
  print(l1); // [12, 17, 33]

any 判断数组中是否有满足指定条件的元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  bool a = l1.any((e) => e > 30);
  print(a); // true

every 判断数组中是否每个元素都满足指定的条件 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  bool a = l1.every((e) => e > 1);
  print(a); // false

take 从索引 0 位置处,取指定个数的元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.take(3);
  print(l2); // (8, 12, 4)

takeWhile 从索引 0 位置处,查询满足指定条件的元素,直到出现第一个不符合条件的元素,然后返回前面符合条件的元素 查看更多

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.takeWhile((e) => e > 1);
  print(l2); // (8, 12, 4)

skip 跳过指定个数的元素,返回后面的元素

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.skip(4);
  print(l2); // (17, 33, 10)

skipWhile 根据指定条件,找到第一个不符合条件的元素,然后将该元素后面的所有元素返回

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.skipWhile((e) => e < 17);
  print(l2); // (17, 33, 10)

sublist 从指定索引处截取数组

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  List<int> l2 = l1.sublist(5);
  print(l2); // [33, 10]
  
  List<int> l3 = l1.sublist(2, 5);
  print(l3); // [4, 1, 17] 含头不含尾

getRange 截取指定索引范围内的元素

  List<int> l1 = [8, 12, 4, 1, 17, 33, 10];
  Iterable<int> l2 = l1.getRange(2,5);
  print(l2); // (4, 1, 17)

whereType 从混合类型的数组中,筛选出指定类型的元素


  List l1 = ["a", 15, "b", false, true, 20, "c",{"name":"AllenSu"}];
  Iterable<String> l2 = l1.whereType();
  Iterable<int> l3 = l1.whereType();
  Iterable<bool> l4 = l1.whereType();
  Iterable<Map> l5 = l1.whereType();
  print(l2); // (a, b, c)
  print(l3); // (15, 20)
  print(l4); // (false, true)
  print(l5); // ({name: AllenSu})

五:"常用"的方法(12 个)

forEach 遍历数组中的元素

  List<int> l1 = [8, 12, 4, 1];
  l1.forEach((e) => print(e)); // 8 12 4 1

map 遍历数组中的所有元素,可以对元素进行处理,并返回新的 Iterable

  List<int> l1 = [8, 12, 4, 6, 22, 34, 10];
  Iterable<bool> l2 = l1.map((e) => e > 10);
  Iterable<String> l3 = l1.map((e) => e > 10 ? "大" : "小");
  Iterable<num> l4 = l1.map((e) => e > 12 ? e / 2 : e * 2);
  print(l2); // (false, true, false, false, true, true, false)
  print(l3); // (小, 大, 小, 小, 大, 大, 小)
  print(l4); // (16, 24, 8, 12, 11.0, 17.0, 20)

toSet 将 List 转换为 Set,得到去重后的元素

  List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
  Set<int> l2 = l1.toSet();
  print(l2); // {8, 12, 6, 22, 10}

asMap 将 List 转换为 Map,key 为原数组的索引,value 为原数组的元素

  List<String> l1 = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
  Map map = l1.asMap();
  print(map); // {0: 周一, 1: 周二, 2: 周三, 3: 周四, 4: 周五, 5: 周六, 6: 周日}

sort 数组排序(原数组发生改变)

  List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
  l1.sort();
  List<String> l2 = ["f","d","b","c","a","e"];
  l2.sort();
  print(l1); // [6, 8, 8, 10, 12, 12, 22]
  print(l2); // [a, b, c, d, e, f]

join 用指定字符连接数组中每个元素,返回 String

  List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
  String str1 = l1.join();
  String str2 = l1.join("");
  String str3 = l1.join(" ");
  String str4 = l1.join(",");
  String str5 = l1.join("-");
  print(str1); // 81286221210
  print(str2); // 81286221210
  print(str3); // 8 12 8 6 22 12 10
  print(str4); // 8,12,8,6,22,12,10
  print(str5); // 8-12-8-6-22-12-10

cast 将一个数组的类型传递给未指定数据类型的数组

  List<int> l1 = [8, 12, 8];
  var l2 = l1.cast(); // 指定 l2 的数据类型和 l1 的一样,都是 int 类型
  l2.add(6);
  print(l1); // [8, 12, 8, 6]
  l2.add("ddd");
  print(l1); // 报错,提示无法将 String 类型的数添加到 int 类型的数组中

List.generate 快速生产 Flutter 中的 Widget

List<int> l1 = [8, 12, 8, 6, 22, 12, 10];
...
children: List.generate(l1.length, (index){
    return Text("$index");
 })

reduce 用指定的函数方式对数组中的所有元素做连续操作,并将结果返回

  List<int> l1 = [1, 2, 3, 4];
  int res1 = l1.reduce((a, b) => (a * b)); // 元素依次相乘
  int res2 = l1.reduce((a, b) => (a + b)); // 元素依次相加
  print(res1); // 1*2*3*4 = 24
  print(res2); // 1+2+3+4 = 10

fold 根据一个现有数组和一个初始参数值 initValue,指定参数条件操作现有数组的所有元素,并返回处理的结果

  List<int> l1 = [1, 2, 3, 4];
  // 2 为初始参数值,后面定义的方法为该初始值和原数组之间的处理方式
  int res1 = l1.fold(2, (a, b) => (a * b)); // 相乘
  int res2 = l1.fold(2, (a, b) => (a + b)); // 相加
  print(res1); // 2*(1*2*3*4) = 48
  print(res2); // 2+(1+2+3+4) = 12

expand 根据现有数组,指定一个处理方式,返回一个 Iterable

  List<int> l1 = [1, 2, 3, 4];
  // 将 l1 数组内的每一个元素都和指定的表达式组相操作
  Iterable<int> l2 = l1.expand((e) => [e + 1]);
  Iterable<int> l3 = l1.expand((e) => [e + 1, e + 2]);
  Iterable<int> l4 = l1.expand((e) => [e + 2, e * 2]);
  Iterable<num> l5 = l1.expand((e) => [e * 2, e / 2]);
  Iterable<int> l6 = l1.expand((e) => [e, e + 1, e + 2]);
  print(l2); // (2, 3, 4, 5)
  print(l3); // (2, 3, 3, 4, 4, 5, 5, 6)
  print(l4); // (3, 2, 4, 4, 5, 6, 6, 8)
  print(l5); // (2, 0.5, 4, 1.0, 6, 1.5, 8, 2.0)
  print(l6); // (1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6)

shuffle 随机排列指定数组(修改了原数组)

  List<int> l1 = [1, 2, 3, 4];
  l1.shuffle();
  print(l1); // [1, 4, 2, 3]
  l1.shuffle();
  print(l1); // [2, 1, 3, 4]

终于写完了,属实不易,可以看到 Dart 中 List 数组中的方法还是比较多的,其中关于查询数据的居多,虽然每个方法都举了一个或者多个例子,不过我觉得还是缺一张总览表,用来记载每个方法的名称和作用,也给大家整理好了,就是下面这几张表了

汇总

"添加"数据的方法
方法名作用
add添加一个元素到数组末尾
addAll合并两个数组
insert在指定索引处插入一个值
insertAll在指定索引处插入一个数组
"删除"数据的方法
方法名作用
remove删除指定元素
removeAt删除指定索引位置处的元素
removeLast删除数组的最后一个元素
clear清空数组
removeWhere根据指定条件删除元素
removeRange删除指定索引范围内的元素(含头不含尾)
"修改"数据的方法
方法名作用
List [index]修改指定索引位置元素的值
fillRange用相同的值替换指定索引范围内的所有元素(含头不含尾)
replaceRange用某一数组替换指定索引范围内的所有元素(含头不含尾)
setRange范围替换数组中的值(含头不含尾)
setAll从指定索引位置开始,使用第二个数组内的元素依次替换掉第一个数组中的元素
"查询"数据的方法
方法名作用
elementAt获取指定索引位置处的元素
contains判断数组中是否含有指定元素
indexOf获取指定元素在数组中的索引
lastIndexOf从后向前查找指定元素在数组中的索引
indexWhere返回第一个满足条件的元素的索引
lastIndexWhere从后向前找,返回第一个满足条件的元素的索引
where根据指定条件,函数筛选每个元素,符合条件的元素组成一个新的 Iterable
firstWhere返回第一个满足条件的元素
lastWhere从后向前查找第一个满足条件的元素
singleWhere获取满足指定条件的唯一元素
retainWhere根据指定条件筛选元素(改变了原数组)
any判断数组中是否有满足指定条件的元素
every判断数组中是否每个元素都满足指定的条件
take从索引 0 位置处,取指定个数的元素
takeWhile从索引 0 位置处,查询满足指定条件的元素,直到出现第一个不符合条件的元素,然后返回前面符合条件的元素
skip跳过指定个数的元素,返回后面的元素
skipWhile根据指定条件,找到第一个不符合条件的元素,然后将该元素后面的所有元素返回
sublist从指定索引处截取数组
getRange截取指定索引范围内的元素
whereType从混合类型的数组中,筛选出指定类型的元素
"常用"的方法
方法名作用
forEach遍历数组中的元素
map遍历数组中的所有元素,可以对元素进行处理,并返回新的 Iterable
toSet将 List 转换为 Set,得到去重后的元素
asMap将 List 转换为 Map,key 为原数组的索引,value 为原数组的元素
sort数组排序(原数组发生改变)
join用指定字符连接数组中每个元素,返回 String
cast将一个数组的类型传递给未指定数据类型的数组
List.generate快速生产 Flutter 中的 Widget
reduce用指定的函数方式对数组中的所有元素做连续操作,并将结果返回
fold根据一个现有数组和一个初始参数值 initValue,指定参数条件操作现有数组的所有元素,并返回处理的结果
expand根据现有数组,指定一个处理方式,返回一个 Iterable
shuffle随机排列指定数组(修改了原数组)

至此,关于 Dart 中 List 数组的常用方法已经总结完毕,显示已接近一万字,这篇文章实在是太肝了,不过整理下来自己也掌握了很多,也相信可以帮助很多人。

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。


结束语

技术是一点一点积累的,大神也不是一天就可以达到的。原地不动就是退步,所以每天进步一点点。

最后,附上一句格言:"好学若饥,谦卑若愚",望共勉。