iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 5
0
Software Development

Dart 語言 - 開啟 Flutter 的鑰匙系列 第 5

Day5:內建型態 (集合) -Lists

前面介紹了數字 (Numbers) 與字串 (Strings) 類,這兩種型態都是針對單一物件做處理。

集合是可以將一連串同樣類型 (numbers, strings, 自定義的類, ... )的項目包在一個物件中。

在 Dart 中,集合主要分為三類:

  • Lists
  • Sets
  • Maps

本篇文章將介紹集合中的 Lists 類。

Lists

List 存放的是一連串有序的物件 (Object),在 List 裡面的項目是可以重複的。

每一個物件存放至 List 中,List 則會自動加上由零開始計算的索引值 (Index),所以每一個 List 最後一個索引值是 list.length - 1 。

定義 List

那麼要如何定義 List 呢?

有兩種 List 格式,一種是固定長度,另一種為可變長度。

可變長度的 List

可變長度的 List 利用中括弧 []定義,同時將該 List 的初始值以逗號分隔填入中括弧中。

如下例:

var list = [1,2,3]; // List<int>

上例中,我們使用 var 來存放 List , 根據 List 裡面的值 Dart 的類型推斷將此 List 的類型設為 List。

若在此之後嘗試將非 int 的值加入,則會發生編譯期的錯誤。

var list = [1,2,3];
list.add('A'); //Compiliation-error

我們亦可以在定義 List 時帶入型態

var list = <int>[1,2,3];

那麼在設定初始值時,就可以避免錯誤的資料。

var list = <int>[1,2,3,'string'];//Compiliation-error

固定長度的 List

前面介紹的 List 可以在執行期動態加入資料,所以 List 的大小會隨著增加數量而改變。

如果我們需要一個固定長度的 List,不允許在執行期新增項目呢?

定義方法:List(int Size)

var list = List(2);
list[0]=0;
list[1]=1;
list[2]=2;//Compiliation-error

固定長度的 List 定義好之後,每一個索引值內的值預設都為 null。

同樣的,我們也可以在定義變數時,設定其型態。

var list = List<int>(3);
list[0] = 1;
list[1] = 'String'; //Compiliation-error

List 取值

List 是有序的,存入 List 時會自動加上索引值,所以我們可以利用物件的索引值取出物件。

取用方式:list[Index]

list[0];

由於 List 的索引值是由 0 開始計算,所以 List 的最後一個索引值為 list.length-1

list.length; //3
list[list.length-1];//3

List 設值

同樣的,在 List 後方加上中括弧,並帶入索引值,可以在修改特定位置的數值。

設值方式:list[Index]=value;

list[0] = 4;

可迭代的 (Iterable)

List 是 Iterable 的子類別,List 也包含迭代的功能,我們可以利用迭代走訪每一個 List 的項目。

迭代方式:

  • 使用 for
var list = [1,2,3,4];
for(var item in list){
	print(item);
}

//1
//2
//3
//4

Hint: 如果你是用 IntelliJ 開發,當在 list 後面輸入 .iter 按下 Enter/Return

IDE 會自動建立一個迭代用的 for 迴圈,如上方範例。

  • 使用 while
var list = [1,2,3,4];

final iter = listOfInts.iterator;
while(iter.moveNext()){
  print(iter.current);
}

//1
//2
//3
//4
  • 為簡化迭代以及避免迭代時使用錯誤的項目,應使用 for 來迭代,避免使用 while。

展開運算子 (Spread Operator)

Dart 2.3 新增了展開運算子 (Spread Operator),利用展開運算子我們可以輕鬆地將兩個 List 結合在一起。

使用方法:...list

var list = [1,2,3];
var list2 = [0, ...list];
print(list2);//[0,1,2,3]

非空展開運算子

在使用展開運算子時,若變數尚未指定數值,那麼就會無法將 List 展開,導致發生錯誤。

可以使用非空展開運算子來避免展開空的 List。

使用方法:...?list

var list1;
var list2 = [0, ...?list1];
print(list2); //[0]

Collection if & Collection for

Dart 2.3 同時也新增了在集合函數中使用 if 以及 for。

Collection if

在初始化 List 時,若裡面有些項目需要根據某些條件才需要加進去,

通常,我們需要建立不需要判斷的 List 內容,接者再使用 if 加上 list.add 動態將項目加進去。

var isRoot = true
var users = [
'user1',
'user2',
'user3'];
if(isRoot) users.add('root');

利用 Collection if 改寫就可以在初始 List 時就將其可變的項目也一併的增加。

var isRoot = true
var users = [
'user1',
'user2',
'user3',
if(isRoot) 'root'];

Collection for

我們也可以在集合類中,使用 for 加入項目。

var listOfInts = [1,2,3];
var listOfString = [
	'#0',
	for(var i in listOfInts) '#$i'
];
print(listOfString);
//[#0, #1, #2, #3]

常用 List 類方法

  • add(E element) : 新增一個項目。
  • addAll(Iterable iterable):附加帶入的 Iterable 所有項目。
  • clear():清除所有項目,List 的長度變為 0 。
  • insert(int index, E element):插入項目至 Index 。
  • remove(Object? value):移除第一個查到的項目。
  • removeAt(int index):移除索引值的項目。
  • removeLast():移除最後一個項目。
  • shufflue():隨機排列原 List。

小結

List 是最常見的集合之一,因有索引值,所以可以快速取出。利用迭代的方式,可以一口氣走訪所有的項目。

在 Dart 2.3 所新增的功能:展開運算子 (Spread Operator)、Collection if 以及 Collection for 可以將部分 List 外的運算移到 List 初始化時做,如此可以快速的在定義函數時就處理完,減少多餘的程式碼。

當然別忘了,List 有分為固定長度與可變長度的,可以依需求定義。


上一篇
Day4:內建型態 - 字串 (Strings)
下一篇
Day6:內建型態(集合) - Sets
系列文
Dart 語言 - 開啟 Flutter 的鑰匙30

尚未有邦友留言

立即登入留言