dart list 数组详解

简介: dart list 数组详解

相比于 js dart list 最明显的一个特点就是可以是强类型。为了能更好的从前端的视角分析 dart list ,从 dynamic 类型开始解释各个方法。如果你还不熟悉 dynamic 可以先看这里 dart 中的 dynamic)

var list = []; //相当于 var list=<dynamic>[]
list[0] = 1;
list[1] = 'a' //ok
复制代码

我们可以看到,当类型为 dynamic 时,效果和 js 差不多。不进行类型检查。下面看几个常用方法。

增加元素

增加元素的方法都是修改原数组,返回  void

在末尾增加一个元素

和 js 的 push 效果一样

list.add(1);
复制代码

在末尾增加多个元素

与 js  的  concat 不同, concat 不修改原来的数组,而是返回连接后的数组。

list.addAll([2,3]);
复制代码

在末尾增加多个元素也可以这样写,用 + 操作符看起来更简洁

print([1,2]+[3,4]); // 1,2,3,4
复制代码

在任意位置增加一个元素

var list=[1,'a'];
list.insert(0,2);
print(list); // [2,1,'a']
复制代码

在任意位置增加多个元素 insertAll

var list = [1, 'a'];
list.insertAll(0, [2, 3]);
print(list); // [2,3,1,'a']
复制代码

删除元素

删除方法都会修改原数组

删除最后一个元素 removeLast

返回被删除的元素,和 js  的 pop 效果一样

list.removeLast(0);
复制代码

在任意位置删除一个元素 removeAt

返回被删除的元素。index 必须在[0,Length) 否则抛异常

list.removeAt(0);
复制代码

根据值删除一个元素 removeAt

成功返回 true,失败返回 false 与 js 不同的是 元素的类型不会自动转换,只能类型和值都相同才会删除成功

var a = ['1', '2', 3, 4];
var isOk = a.remove(1);
print(isOk); //  false
isOk = a.remove('1');
print(isOk); //  true
复制代码

删除范围内多个元素 removeRange

返回 void。range 必须在[0,Length) 否则抛异常。被删除的范围含头不含尾

list.removeRange(0,1); 
复制代码

根据条件删除元素 removeWhere

返回 void 删除不成功不报错,和 remove 一样,类型和值都匹配的元素才能删除成功

var a = ['1', '2', 1];
a.removeWhere((item) => item == 1);
print(a); // [ '1','2']
复制代码

根据条件保留元素,也就是删除不符合条件的元素 retainWhere

返回 void

list.retainWhere((item) => item>10)
复制代码

删除所有元素

list.clear();
复制代码

也可以用

list = [];
复制代码

修改一个元素

list[0] = 1;
复制代码

修改多个元素 setAll

返回  void ,修改的长度不能超过数组的长度,否则抛异常。

var a = <int>[1, 4, 5];
a.setAll(1, [2, 3]);
print(a); // [ 1,2,3]
复制代码

还有几个方法,但都可以方便用 setAll 替代

  1. fillRage,
  2. repalceRage
  3. setRange

查询元素

查询元素的方法都不修改原数组

查询元素的类型和值都得得相同才算是匹配成功

获得一个元素 elementAt

var n= list.elementAt(0);
复制代码

也可以用

var n = list[0] 
复制代码

判断数组中是否含有指定的一个元素  contains

var list=[1]
list.contains(1); //true
list.contains('1') //false
复制代码

获取指定一个元素在的索引  indexOf

查不到返回 -1

var list=[1,1,2]
list.indexOf(1); // 0
list.indexOf(1,1) //false 因为是从位置 1 查找。这个不常用,知道就行
复制代码

获取指定一个元素在的索引,从后向前找  lastIndexOf

查不到返回 -1 和 indexOf 用法一样,只是从后面开始查找

var list=[1,1,2]
list.indexOf(1); // 0
list.lastIndexOf(1)  // 1
list.lastIndexOf(1,0)  // 0 不常用,知道就行
复制代码

根据条件只返回一个符合条件的元素 indexWhere, lastIndexWhere

查不到返回 -1

var list=[1,1,2,2,2,3];
list.indexWhere((item)=>item==2); // 2
list.lastIndexWhere((item)=>item==2); // 4
复制代码

根据条件查询元素  where, firstWhere,lastWhere

返回 iterable 这个是比较常用的方法

var list=[1,1,2,2,2,3];
list.indexWhere((item)=>item==2); // 2
复制代码

firstWhere,lastWhere 可以用 where 替代,只是代码会更简洁一些

var list=[1,1,2,2,2,3];
var nums= list.indexWhere((item)=>item>1);
print(nums.first); // 获取第一个元素
print(nums.last); // 获取最后一个元素
复制代码

保证只有一个元素 singleWhere

如果符合条件的元素不是 1 个会抛异常。singleWhere 的意义在于保证 有且只有一个

相当于 我发誓...

single 属性也是一样的,如果元素多于一个,调用这个属性会引发异常

获取范围内多个元素  sublist,getRange,take,takeWhile

var list=[1,2,3,4,5];
var nums= list.sublist(4);
print(nums); // 5
nums= list.sublist(0,2);
print(nums); // [1,2]
nums= list.getRange(0,2);
print(nums); // (1,2)
复制代码

sublist,getRange都是返回范围的元素,但是sublist返回的是 List,getRange 返回的 是 iterable

sublist的 第二个索引参数可以为空,getRange第二个索引参数不能为空。从这点看来 getRange 更加名副其实,sublist 更象 js 的 sllice

take是从索引0取指定个数元素 take(3) 相当于 getRange(0,3)takeWhile 是 从索引 0位置 处开始,获取所有满足条件的元素。

其它常用方法

有的方法和 js 的差不多,就不举例了。

  1. forEach
  2. map
  3. very
  4. any
  5. join

还有一个 shuffle 方法是随机打乱原数组的, js 里没有这样的方法,不过 shuffle 基本上也没什么出镜的机会。

快速生产数据 generate

构造函数之一

List<int>.generate(3, (int index) => index * index); // [0, 1, 4]
复制代码

把 Iterable 转成 List 对象 toList

toList还是很常用的。比如 map 函数一般会接一个 toList

[1,2,3].map((item)=>item+1).toList()
复制代码

降低维度 reduce,fold

fold 需要初始值,reduce不需要。

var a = [1, 2, 3, 4];
var c = a.reduce((a, b) => a + b);
print(c); // 10
var d = a.fold(1, (a, b) => a + b);
print(d); // 1 + (1 + 2 + 3 + 4)
复制代码

扩充 expand

var a = [1, 2];
var c = a.expand(item=>item[item+1,item+1]);
print(c); // (2,2,3,3)
复制代码

根据原数组创新一个新数组 of

构造函数之一。 返回 List. 相当于 js 的 list.splice(0)。

var a=[1,2,3];
var b=List.of(a);
b.add(4);
print(a); //1,2,3
print(b); //1,2,3,4
复制代码

根据 iterable 对象创新一个新数组 from

构造函数之一。和 of 一样返回 List. 和 of  一样都是创建新数组,但来源不同,from的源是 iterable 对象。也就是说 from 可以的 of 可能不可以。

var a=[1,2,3];
var b=List.from(a);
b.add(4);
print(a); //1,2,3
print(b); //1,2,3,4
//下面的 from 可以 of 不可以
List<dynamic> dynList = ...some JSON value...; 
List<Map<String, dynamic>> fooList = List.from(dynList.where((x) => x is Map && x["kind"] == "foo"));
复制代码

排序 sort

和 js 一样用法。

var numbers = ['two', 'three', 'four']; // Sort from shortest to longest. 
numbers.sort((a, b) => a.length.compareTo(b.length)); print(numbers); // [two, four, three]
复制代码

也可以不用 compareTo,只要返回的值是 int 就行,这样就和 js 的写法一样了。

var numbers = ['two', 'three', 'four']; // Sort from shortest to longest. 
numbers.sort((a, b) => a.length - b.length)); print(numbers); // [two, four, three]
复制代码

查询特定类型的元素 whereType

var a = [1, 'a'];
var b = a.whereType<int>();
//不建议这样写
Iterable<String> c = a.whereType();
print(b); // (1)
print(c); // (a)
复制代码

虽然示例的两种写法都可以,但是建议 var b = a.whereType<int>(); 这种写法。

用 var 声明的类型 dart 会进行类型推断。比自己写类型要好。

获得 List 的视图  cast

如果你知道数据库的视图,这里的视图就不难理解了。就是不创新新的 List,只是生成视图。一个 list 可以生成多个视图。只要图图的类型可以从 原数组的类型转换就可以。一般来说是从子类向父类转

var a=[1,2,3,4];
  var c=a.cast<double>(); //生成 double 视图,因为 int 可以转成 double
  a[0]=c[0].ceil();  //可以调用 doulbe的方法了
  c.removeLast();  //操作视图也就是操作原数组
  print(c);   // 1,2,3
  print(a);   //  1,2,3
复制代码

转成其它类型

  1. toSet
  2. toString
  3. asMap

如果想对数组数据去重 ,toSet是一个选择。 asMap 要注意是只是生成 map 的视图而已,是让你可以暂时把 list 当作 map 来用。

前面的例子大多是 dynamic的,不验证类型,但如果指明类型,那么就必须是这样的类型。

var list=[1,2,3];
list.add('a');//  错误
复制代码

var list=[1,2,3]; 相当于是 var list = <int>[1,2,3]; 因为后面的数据都是 int 型,所以dart就认为 list 都应该是 int 型的数据。这时如果想要不考虑类型,需要显示的用 dynamic 指明

var list=<dynamic>[1,2,3];
list.add('a');// 正确
复制代码

参考

目录
相关文章
|
1月前
如何实现数组和 List 之间的转换?
如何实现数组和 List 之间的转换?
|
1天前
|
Dart
Dart之集合详解(List、Set、Map)
Dart之集合详解(List、Set、Map)
7 1
|
20天前
|
存储 NoSQL 安全
Redis第六弹-List列表-(相当于数组/顺序表)Lpush key element-一次可以插入多个元素(假如key已经存在,并且key对应的value并非是list,则会报错)
Redis第六弹-List列表-(相当于数组/顺序表)Lpush key element-一次可以插入多个元素(假如key已经存在,并且key对应的value并非是list,则会报错)
|
1月前
|
存储 索引 Python
多数pythoneer只知有列表list却不知道python也有array数组
多数pythoneer只知有列表list却不知道python也有array数组
34 0
|
1月前
使用List中的remove方法遇到数组越界
使用List中的remove方法遇到数组越界
40 2
|
1月前
|
Java
Java中拷贝list数组如何实现
Java中拷贝list数组如何实现
18 0
|
1月前
|
Java
java List数组根据给定大小分割数组
在获取到很长的数组时,一次性处理数据量太大,需要分批处理,这就需要分批处理了。 1、使用List的subList,封装方法 2、google工具类型Lists的partition 经测试个人推荐使用第一种方法,效率上快了10几倍,估计是因为没有重新生成数组的原因
61 8
|
1月前
|
存储 C# 索引
C# | 比较IEnumerable、List、数组
IEnumerable`定义了一组用于枚举集合的方法,包括`GetEnumerator`方法,该方法返回一个实现了`IEnumerator`接口的对象,用于枚举集合中的每个元素。`List`和数组都可以使用`foreach`循环来遍历其中的元素,这是因为它们都实现了`IEnumerable`接口。 由于数组在内存中开辟了一段连续的空间,因此可以直接通过索引访问元素,访问速度很快。而 List 则需要通过指针或引用来访问元素,速度相对较慢。 由于数组的大小是固定的,当需要添加或删除元素时,需要重新创建一个新数组,将原数组中的元素复制到新数组中,并添加或删除元素。
93 0
C# | 比较IEnumerable、List、数组
|
1月前
|
XML Java 数据格式
spring怎么去引用/注入集合/数组类型和 怎么通过 util 名称空间创建 list以及 怎么去通过级联属性赋值
spring怎么去引用/注入集合/数组类型和 怎么通过 util 名称空间创建 list以及 怎么去通过级联属性赋值
48 0
|
1月前
Spring-数组、List、Set、Map、Properties依赖注入格式
Spring-数组、List、Set、Map、Properties依赖注入格式
31 0