DART2 Prima Plus - 第二课 - LIST
在本系列第二篇文章中,我将完全专注于列表操作。
引言
本文是学习 Dart 语言(新一代语言)系列的第二篇。Dart 团队以几乎与 .NET Core 相同的速度升级语言。随着 Flutter 将其作为应用程序开发的主要语言,我相信它很快就会成为主流。
在本文中,我将讨论 List
类型,它是普通 Array
和 C++ List
的结合体,类似于 C# 的 System.Collection.Generic.List
数据结构。
背景
我将讨论 List
类的以下属性和方法,该类在 Dart:Core
包中定义,由于 DART
是开源的,你可以在 list.dart 文件中查看其代码。我将讨论 List
类提供的以下属性。定义和声明取自 DART 网站。如果你需要了解如何创建项目,请参考本系列的第一篇文章此处。
- 任务 #1 创建
List(int length)
- 创建一个给定length
的列表。List.filled(int length,E fill,{bool growable:false})
- 创建一个给定length
的固定长度列表,并用fill
参数初始化每个位置的值。List.generate(int length, E generator(int index),{bool gowable:true}
) - 根据generator
函数和length
参数生成一个值列表。List.unmodifiable(Iterable elements)
- 创建一个包含所有元素的不可修改列表。List.from(Iterable elements,{bool growable:false})
- 创建一个包含所有元素的列表。static List.copyRange<T>(List<T> target, int at, List<T> source, [int start, int end])
: 将source
列表复制到target
,从at
开始,你还可以指定要复制的源列表的start
(包含)和end
(不包含)。
- 任务 #2 属性
first
- 返回列表的第一个元素。last
- 返回列表的最后一个元素。length
- 返回列表的长度。reversed
- 反转列表。isEmpty
- 检查列表是否为空。isNotEmpty
- 检查列表是否非空。runtimeType
- 对象类型,类似于 C# 中的类型。
- 任务 #3 添加/删除数据
add(E value), addAll(Iterable<E> iterable)
- 将值/可迭代对象添加到列表。asMap()
- 返回列表的不可修改的 Map,键是index
,列表项是value
。fillRange(int start, int end, [ E fillValue ])
/Iterable<E> getRange(int start, int end)
- 将从start
(包含)到end
(不包含)范围内的对象设置为给定的fillValue
/ 返回一个在从start
(包含)到end
(不包含)范围内的对象上迭代的 Iterable。insert(int index, E element)/ insertAll(int index, Iterable<E> iterable)
- 将对象插入此列表的index
位置 / 将iterable
的所有对象插入此列表的index
位置 & 将iterable
的所有对象插入此列表的index
位置。setAll(int index, Iterable<E> iterable) /setRange(int start, int end, Iterable<E> iterable, [ int skipCount = 0 ])
- 将iterable
的对象(跳过前skipCount
个对象)复制到列表的start
(包含)到end
(不包含)范围。take(int count)/takeWhile(bool test(E value)
) - 返回此可迭代对象的前count
个元素的惰性可迭代对象。/ 返回满足test
的前导元素的惰性可迭代对象。fold<T>(T initialValue, T combine(T previousValue, E element))
- 通过迭代地将集合的每个元素与现有值组合,将集合简化为单个值。join([String separator = "" ])
- 将每个元素转换为 String 并连接字符串。remove(Object value)/removeAt(int index)/removeLast()
- 从此列表中删除值的第一次出现 / 从此列表中删除index
位置的对象 / 弹出并返回此列表中的最后一个对象。removeRange(int start, int end)
- 删除从start
(包含)到end
(不包含)范围内的对象。
- 任务 #4 查找数据和数据位置
indexOf(E element, [ int start = 0 ])
- 返回此列表中element
的第一个索引。elementAt(int index)
- 返回第index
个元素。lastIndexOf(E element, [ int start ])
- 返回此列表中element
的最后一个索引。any(bool f(E element))
- 检查此可迭代对象中是否有任何元素满足测试。sublist(int start, [ int end ])
- 返回一个新列表,其中包含从start
(包含)到end
(不包含)范围内的对象。where(bool test(E element))
- 返回一个满足谓词test
的所有元素的新惰性 Iterable。singleWhere(bool test(E element))
- 返回满足test
的单个元素。firstWhere(bool test(E element), { E orElse() })
- 返回满足给定谓词test
的第一个元素。lastWhere(bool test(E element), { E orElse() })
- 返回满足给定谓词test
的最后一个元素。retainWhere(bool test(E element))
- 从此列表中删除所有不满足test
的对象。removeWhere(bool test(E element))
- 从此列表中删除所有满足test
的对象。
Using the Code
我将本教程分为四个任务,我将分别讨论每个任务。
任务 #1
在本节中,我将讨论 DART 提供的用于在 List
中创建或初始填充数据的各种创建方法,我在此处涵盖了所有 6 种方法。你可以在随附的 zip 文件中查看 creation.dart 文件以了解相同内容。
void creation()
{
// 1.0 Basic List
List<int> listOfInt = new List<int>();
// 1.1 with Length
List<int> listOfIntWithLength = new List<int>(5);
//1.2 Using List.filled when list is fixed length
List<int> listofIntFilledFixed = new List<int>.filled(5, 1);
try{
//this will throw error
listofIntFilledFixed.add(5);
}
catch(ex)
{
print(ex);
}
// 1.2(a) using List.filled, now list is growable
List<int> listofIntFilledGrowable = new List<int>.filled(5, 1,growable:true);
listofIntFilledGrowable.add(5);
// 1.3 using List.generate, you can specify your own function to provide value to list
// => is way to write shorthand function, the list would contain 1,2,3,4,5
// as list in dart is zero index based
List<int> listofIntGenerate = new List<int>.generate(5,(int index)=> index+1);
//1.5 Using List.from, it will also have 1,2,3,4,5
List<int> listOfIntFrom = new List<int>.from(listofIntGenerate);
// 1.4 Using List.unmodifiable list with created list
List<int> listOfIntunmodifiable = new List<int>.unmodifiable(listofIntGenerate);
try{
//this will throw error
listOfIntunmodifiable.add(5);
}
catch(ex)
{
print(ex);
}
//1.6 Using List.copyRange, you need to specify length of target before hand
List<int> listOfIntWithcopyRange = new List<int>(3);
List.copyRange(listOfIntWithcopyRange, 0, listOfIntunmodifiable,0,3);
}
我在代码本身中提供了相关的注释以演示各种代码片段。至此,我们完成了任务 #1。
任务 #2
在此任务中,我将演示 DART:List
类提供的 first
、last
、length
、reverse
、isEmpty
、isNotEmpty
、runtimeType
属性的使用。代码写在 property.dart
中,该文件在随附的 zip 文件中。
void properties()
{
// Create List with pre filled items : 1,2,3,4,5
List<int> listIntProperties = new List.generate(5,(int index)=>index+1,growable: true);
// Demonstrate use of first, last and length property
print("First : ${listIntProperties.first}, Last : ${listIntProperties.last}
and number of elements are ${listIntProperties.length}");
//-- Print list in reverse
listIntProperties.reversed.forEach((int item){ print('item ${item}');});
//-- Demonstrate use of isEmpty, isNotEmpty, and runtimeType
print("isEmpty : ${listIntProperties.isEmpty}, isNotEmpty : ${listIntProperties.isNotEmpty}
and ObjectTyp ${listIntProperties.runtimeType}");
}
至此,我们完成了任务 #2。
任务 #3
在此代码中,我将讨论 add(E value)
、addAll(Iterable<E> iterable)
、asMap()
、fillRange(int start, int end, [ E fillValue ])/ Iterable<E> getRange(int start, int end)
、insert(int index, E element)/ insertAll(int index, Iterable<E> iterable)
。在 listadd.dart
中的 listadd()
中查找以下代码。
void listadd()
{
//-- this list will contain 1,2,3,4,5
List<int> listIntAdd = new List.generate(5,(int index)=>index+1,growable: true);
// this list will contain 10,11
List<int> listIntAdd2 = new List.generate(2,(int index)=>index+10,growable: true);
// Task 3.1 add and addAll
listIntAdd.add(6);
// List.join (Task#3.8), join all element as string, I will talking more about in its separate section.
print("After Task 3.1 add (listIntAdd)= " + listIntAdd.join(","));
listIntAdd.addAll(listIntAdd2);
print("After Task 3.1 addAll (listIntAdd) = " + listIntAdd.join(","));
//Task 3.2, converting it to map, map is key value data structure,
//if you have C++ background, its similar to stl::map
// otherwise if you from C# background its similar to Dictionary
print("Task#3.2 asMap()");
listIntAdd2.asMap().forEach((key,value){ print("key ${key} value is ${value}");});
//Task 3.3 fillRange and getRange, here i have created list with 3 element, I would fill all with 5
List<int> listIntfillRange = new List.generate(3,(int index)=>5,growable: true);
listIntfillRange.fillRange(0, 3, 5);
print("After Task 3.3 fillRange (listIntfillRange) = " + listIntfillRange.join(","));
// Now for checking getRange, we will get data from listIntAdd, we will get range starting
// from 3rd element to 5th, so overall 2 element would be displayed
print("After Task 3.3 getRange (listIntAdd) = " + listIntAdd.getRange(3,5).join(","));
//Task 3.4 insert and insert all
// I would insert element 7 at 2nd location
listIntfillRange.insert(2,7);
print("After Task 3.4 insert (listIntfillRange) = " + listIntfillRange.join(","));
listIntfillRange.insertAll(2, listIntAdd2);
print("After Task 3.4 insertAll (listIntfillRange) with (listIntAdd2) = " + listIntfillRange.join(","));
}
对于第二个代码演示,我将讨论 setAll(int index, Iterable<E> iterable) /setRange(int start, int end, Iterable<E> iterable, [ int skipCount = 0 ])
、take(int count)/takeWhile(bool test(E value))
、fold<T>(T initialValue, T combine(T previousValue, E element))
、remove(Object value)/removeAt(int index)/removeLast()
、removeRange(int start, int end)
,这些代码在 listadd.dart
的 listadd2()
中。
void listadd2()
{
//-- this list will contain 1,2,3,4,5
List<int> listIntAdd = new List<int>.generate(5,(int index)=>index+1,growable: true);
// this list will contain all zero
List<int> listIntAdd2 = new List<int>.generate(5,(int index)=>0,growable: true);
//Task3.5 setAll
print("Task 3.5 Before setAll (listIntAdd2) = " + listIntAdd2.join(","));
listIntAdd2.setAll(0, listIntAdd);
print("Task 3.5 After setAll (listIntAdd2) = " + listIntAdd2.join(","));
//Task 3.6 take/takeWhile
print("Task 3.6 take (listIntAdd2) = " + listIntAdd2.take(3).join(","));
// this will take element which is smaller than 4
print("Task 3.6 takeWhile (smaller than 4) (listIntAdd2) =
" + listIntAdd2.takeWhile((int item) => item <= 3 ).join(","));
//Task 3.7 fold, here we will calculate sum of all element
print("Task 3.7 fold (listIntAdd2) Initial Val= " + listIntAdd2.join(","));
// here I used toString to convert resulting integer to string to be displayed with print
print("Task 3.7 fold (listIntAdd2) = " + listIntAdd2.fold(0, (prev,element)=>prev+element).toString());
//Task 3.9 remove,removeAt,removeLast
print("Task 3.9 (listIntAdd2) Initial Val= " + listIntAdd2.join(","));
//remove 5 from listIntAdd2
listIntAdd2.remove(5);
print("Task 3.9 remove (listIntAdd2) = " + listIntAdd2.join(","));
//remove from post 2 from listIntAdd2
listIntAdd2.removeAt(2);
print("Task 3.9 removeAt (listIntAdd2) = " + listIntAdd2.join(","));
//removeLast from listIntAdd2
listIntAdd2.removeLast();
print("Task 3.9 removeAt (listIntAdd2) = " + listIntAdd2.join(","));
//Task 3.10 removeRange remove first two element from list
print("Task 3.10 (listIntAdd) Initial Val= " + listIntAdd.join(","));
listIntAdd.removeRange(0, 2);
print("Task 3.10 removeAt (listIntAdd) = " + listIntAdd.join(","));
}
至此,我们完成了任务 #3。
任务 #4
在以下代码中,我将讨论 indexOf(E element, [ int start = 0 ])
、elementAt(int index)
、lastIndexOf(E element, [ int start ])
、any(bool f(E element))
、sublist(int start, [ int end ])
、where(bool test(E element))
。示例在 where.dart
的 listwhere()
函数中。
listwhere(){
//-- this list will contain 1,2,3,4,5,6,7,8
List<int> listIntWhere= new List<int>.generate(8,(int index)=>index+1,growable: true);
// Task 4.1 indexOf, let find index of 6, it should be 5th, as list is zero based
print("Task 4.1 indexOf (listIntWhere) InitialVal= " + listIntWhere.join(","));
print("Task 4.1 indexOf (listIntWhere)= " + listIntWhere.indexOf(6).toString());
// Task 4.2 elementAt, let find element at 5th, it should be 6, as list is zero based
print("Task 4.2 elementAt (listIntWhere) InitialVal= " + listIntWhere.join(","));
print("Task 4.2 elementAt (listIntWhere)= " + listIntWhere.elementAt(5).toString());
// Task 4.3 lastIndexOf, let create new list with duplicate value
// it will contain 0,1,2,0,1,2
List<int> listDuplicate = new List.generate(6, (int x)=> x<3?x:x-3);
print("Task 4.3 lastIndexOf (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.3 lastIndexOf (listDuplicate)= " + listDuplicate.lastIndexOf(1).toString());
// Task 4.4 any, let find does list contain item 2
print("Task 4.4 any (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.4 any (listDuplicate)= " + listDuplicate.any((int item)=>item==2).toString());
// Task 4.5 sublist, let create sublist from 3 to 6 item
print("Task 4.5 sublist (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.5 sublist (listDuplicate)= " + listDuplicate.sublist(3,6).join(","));
// Task 4.6 where, let find item divisible by 2
print("Task 4.6 where (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.6 where (listDuplicate)= " + listDuplicate.where((int item)=> item%2==0).join(","));
}
最后但并非最不重要的是,在以下代码中,我将讨论 singleWhere(bool test(E element))
、firstWhere(bool test(E element), { E orElse() })
、lastWhere(bool test(E element), { E orElse() })
、retainWhere(bool test(E element))
、removeWhere(bool test(E element))
。示例在 where.dart
的 listwhere2()
函数中。
listwhere2(){
//-- this list will contain 1,2,3,4,5,6,7,8
List<int> listIntWhere= new List<int>.generate(8,(int index)=>index+1,growable: true);
// Task 4.7 singleWhere, lets find single element in the list
print("Task 4.7 singleWhere (listIntWhere) InitialVal= " + listIntWhere.join(","));
print("Task 4.7 after singleWhere (listIntWhere)= " +
listIntWhere.singleWhere((int item)=>item==2).toString());
try{
listIntWhere.singleWhere((int item)=>item==9);
}
catch(ex)
{
print("Task 4.7 after singleWhere (listIntWhere) (from catch) notFound = " + ex.toString());
}
// Task 4.8 firstWhere, advantage of firstWhere is that you can specify the default element
// in case element not found
// create the list, it will contain 0,1,2,3,0,1,2,3
List<int> listDuplicate = new List.generate(8, (int x)=> x<4?x:x-4);
print("Task 4.8 firstWhere (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.8 after firstWhere (listDuplicate)= " +
listDuplicate.firstWhere((int item)=>item==2).toString());
print("Task 4.8 after firstWhere (listDuplicate) notFound (return -1)= " +
listDuplicate.firstWhere((int item)=>item==10,orElse: ()=>-1).toString());
// Task 4.9 lastWhere, advantage of lastWhere is that you can specify the default element
// in case element not found
print("Task 4.9 lastWhere (listDuplicate) InitialVal= " + listDuplicate.join(","));
print("Task 4.9 after lastWhere (listDuplicate)= " +
listDuplicate.lastWhere((int item)=>item==2).toString());
print("Task 4.9 after lastWhere (listDuplicate) notFound (return -1)= " +
listDuplicate.lastWhere((int item)=>item==10,orElse: ()=>-1).toString());
// Task 4.10 retainWhere, retain element in list that is divisible by 2
print("Task 4.10 retainWhere (listDuplicate) InitialVal= " + listDuplicate.join(","));
listDuplicate.retainWhere((int x)=> x%2==0);
print("Task 4.10 after retainWhere (listDuplicate) = " + listDuplicate.join(","));
// Task 4.11 removeWhere, remove element in list that is not divisible by 2
print("Task 4.11 removeWhere (listIntWhere) InitialVal= " + listIntWhere.join(","));
listIntWhere.removeWhere((int x)=> x%2!=0);
print("Task 4.11 after removeWhere (listIntWhere) = " + listIntWhere.join(","));
}
至此,我们完成了任务 #4。
关注点
- 语言规范:http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf
- Dart 网站:https://dart.ac.cn/
- 文章 GitHub:https://github.com/thatsalok/FlutterExample/tree/master/darttutorial2
Flutter 教程
DART 系列
历史
- 2018 年 7 月 8 日:第一个版本