Trước khi tìm hiểu về Collection của ngôn ngữ Dart thì chúng ta cùng đi qua một số khái niệm về hàm và phương thức trước nhé.
1. Ngôn ngữ Dart: hàm và phương thức
1.1 Hàm (Functions)
Trong lập trình máy tình, khi ta nói đến một hàm hay một phương thức tức là ta đang nói đến một block code có thể thực hiện một nhiệm vụ cụ thể. Block code đó được đặt tên và hàm sẽ được gọi bằng cách sử dụng cái tên này bất cứ khi nào 1 tác vụ cần được thực hiện. Điều này giúp đỡ mất công ngồi viết đi viết lại những dòng code giống nhau, bạn đơn giản chỉ cần gọi tên của hàm đó lên thôi.
1.2 Cách hàm hoạt động
Giống như các hàm toán học, các hàm lập trình sẽ lấy một input, được biết như là tham sốđể thực hiện một vài phép toán trên tham số đó rồi sau đó trả lại kết quả ra output.
Nó gần giống như một băng chuyền trong một nhà máy. Các mặt hàng đi vào máy từ đầu này và đi ra ở đầu kia của băng chuyền. Chúng được sửa đổi hoàn toàn thông qua quá trình đó. Vì máy không thay đổi trong suốt vòng đời của nó cho nên nó sẽ sửa đổi mọi mặt hàng đi vào theo cùng một cách giống nhau.
1.3 Hàm trong ngôn ngữ Dart
Chúng ta có thể chia hàm trong ngôn ngữ Dart thành hai loại lớn hơn đó là:
- Những hàm được tích sẵn trong Dart
- Những hàm người dùng tự định nghĩa
Hàm người dùng tự định nghĩa là những hàm bạn phải tự tạo ra. Những bài viết sau sẽ nói rõ hơn khái niệm này còn bây giờ bạn không cần quan tâm nó lắm.
Hàm tích sẵn trong ngôn ngữ Dart là những hàm đã được xác định trước bởi Dart và cũng là một phần trong thư viện của nó. Tất cả việc chúng ta cần làm là gọi tên chúng để sử dụng
Câu lệnh in mà chúng ta sử dụng từ đầu series đến giờ cũng được gọi là một hàm tích sẵn.
main() {
var printMe = "Hello World";
print(printMe);
}
Trong đoạn code ở trên, print
là một phương thức thực hiện một nhiệm vụ cụ thể đó là in. printMe
là một tham số để chúng ta truyền qua phương thức và “Hello World” là kết quả output. Chúng ta đã sử dụng những hàm này trong suốt thời gian qua đó các bạn.
print
là một phương thức và nó là một phương thức rất đơn giản, chỉ yêu cầu truyền cho nó một tham số có thể thuộc bất kỳ kiểu nào. Tuy nhiên, hầu hết các phương thức không đơn giản như vậy nó yêu cầu bạn gọi trên một đối tượng. Ví dụ, objectName.method(arguments)
có nghĩa là phương thức đang được gọi trên objectName
và arguments
là các tham số được truyền cho method
. Phương thức sẽ thực hiện một vài hành động trên dữ liệu được chứa trong objectName
.
Hầu hết các phương thức cho phép bạn chỉ truyền một tham số của một kiểu dữ liệu cụ thể. Hãy thử gọi indexOf
một phương thức được tích hợp sẵn trong Dart để hiểu rõ hơn cách hoạt động của nó nhé.
indexOf
được gọi trên đối tượng là một chuỗi và bạn sẽ truyền cho nó một tham số kiểu String
. Nó được sử dụng để tính vị trí bắt đầu của một chuỗi con nằm bên trong chuỗi cha được chỉ định.
Index là vị trí của một đối tượng. Trong ngôn ngữ Dart thì nó luôn bắt đầu với số 0
main() {
String s1 = "hello";
print(s1.indexOf("ll"));
}
Output: 2
Trong đoạn code trên, s1
chính là đối tượng. Chúng ta sẽ gọi phương thức indexOf
trên đối tượng s1
. ll
là tham số mà chúng ta sẽ truyền qua. Output hiển thị là 2 bởi vì vị trí bắt đầu của chuỗi con ll
là thứ 2 trong chuỗi cha là “Hello World”.
Bắt đầu từ thời điểm này trở đi, chúng ta sẽ sử dụng những hàm tích sẵn này trong xuyên suốt series.
2. Giới thiệu về collections trong ngôn ngữ Dart
Cấu trúc dữ liệu là cách lưu trữ, tổ chức dữ liệu có thứ tự, có hệ thống để dữ liệu có thể được sử dụng một cách hiệu quả.
Không giống như hầu hết các ngôn ngữ lập trình, Dart không có một bộ sưu tập lớn các cấu trúc dữ liệu tích hợp sẵn. Thay vào đó, nó có ba bộ sưu tập tích hợp cốt lõi có thể được sử dụng để tạo bộ sưu tập dựa trên nhu cầu của cá nhân. Ba tập hợp đó là List, Set và Map.
Như được thảo luận ở trên, List
, Set
, và Map
là tất cả các kiểu trong ngôn ngữ Dart. Một biến có thể thuộc một trong ba kiểu trên cùng với các kiểu gốc mà chúng ta đã thảo luận ở các bài viết trước. Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu chi tiết từng collection.
3. List: The Dart Array
Arrays là một trong những kiến trúc dữ liệu phổ biến và quan trọng nhất của ngôn ngữ lập trình. Tuy nhiên trong ngôn ngữ Dart thì không có Array mà thay vào đó là List. List sẽ có những lợi thế cũng như hạn chế riêng so với Array.
List là một tập hợp có thứ tự của các đối tượng. Điều này có nghĩa là mỗi phần tử trong list đều có một vị trí cố định.
Danh sách thuộc kiểu List
3.1 Tạo ra một List
Có nhiều cách để tạo ra một list, hãy tìm hiểu những cách phổ biến dưới đây nhé!
Sử dụng Literals
Cách đơn giản nhất là sử dụng literals cùng với dấu ngoặc vuông []
.
Syntax như sau:
Chúng ta bắt đầu với từ khóa var
theo sau là một tên nhận dạng riêng (listName
). Sau đó dùng dấu =
rồi tới dấu ngoặc vuông. Bên trong dấu ngoặc vuông là những phần tử được phân tách bằng dấu ,
.
Nhìn đoạn code bên dưới đây để dễ hình dung hơn nha các bạn.
main() {
var simpleList = [1,2,3];
print(simpleList);
}
Output: [1, 2, 3]
Ở dòng var simpleList = [1,2,3];
của đoạn code bên trên, chúng ta đã khai báo và gán giá trị cho một danh sách với 3 phần tử
Khi chúng ta sử dụng phương thức print để in ra danh sách trên thì output sẽ hiển thị một danh sách hoàn chỉnh bao gồm cả dấu ngoặc đơn.
Bạn có nhớ chúng ta từng nói rằngList
là một kiểu khi chúng ta thảo luận về kiểu dữ liệu không? Trong đoạn code trên, Dart đã tự suysimpleList
là một kiểuList<int>
(mộtList
với những phần tử kiểuint
)
Sử dụng hàm dựng (Constructor)
Bạn cũng có thể khai báo một danh sách bằng cách sử dụng một hàm dựng list. Một hàm dựng list tạo ra một đối tượng sử dụng từ khóa List
theo sau là dấu ngoặc đơn ()
.
Syntax sẽ như sau:
Khi chúng ta tạo một danh sách bằng cách sử dụng syntax bên trên, chúng ta sẽ nhận được một danh sách rỗng. Hãy xem ví dụ bên dưới nhé!
main() {
var listOfVegetables = List();
print(listOfVegetables);
}
Output: []
Khi chúng ta in listOfVegetables
trong đoạn code bên trên, chúng ta sẽ nhận được một danh sách rỗng bởi vì bên trong dấu ngoặc đơn không có phần tử nào cả.
Sử dụng kiểu chỉ định
Thay vì phụ thuộc vào kiểu tự suy của Dart, chúng ta có thể tự chỉ định kiểu mà danh sách nên chứa.
Hãy kiểm tra listOfVegetables
có phải chỉ có thể chứa dạng chuỗi không nhé!
main() {
var listOfVegetables = List<String>();
print(listOfVegetables is List<String>);
}
Output: true
Ở dòng print(listOfVegetables is List);
của đoạn code ở bên trên, chúng ta đang kiểm tra xem thử liệu listOfVegetables
có phải là List<String>
sử dụng toán tử is
. Output sẽ hiển thị true
.
3.2 Làm việc với List
Như đã thảo luận, List là một kiểu của đối tượng và nó có những phương thức cũng như thuộc tính cụ thể.
Những phương thức và thuộc tính đó là gì?Hãy cùng khám phá trong phần bên dưới nhé!
Indexing
Vị trí của phần tử đầu tiên trong danh sách sẽ là 0.
Bởi vì mỗi phần tử đều có một vị trí riêng của nó cho nên một danh sách có thể chứa nhiều phần tử trùng nhau. Mặc dù trùng nhau nhưng chúng đều có vị trí khác nhau. Ví dụ chúng ta có thể có một danh sách với 5 phần tử giống nhau như bên dưới.
Truy vấn một phần tử
Để truy vấn một phần tử tại một vị trí cụ thể chúng ta có thể sử dụng dấu ngoặc vuông []
.
Syntax sẽ như sau:
Xem ví dụ bên dưới:
main() {
var listOfVegetables = ['potato', 'carrot', 'cucumber'];
print(listOfVegetables[1]);
}
Output: carrot
Trong ví dụ bên trên chúng ta truy vấn phần tử thứ hai của danh sách listOfVegetables
, phần tử mà được index là 1.
Tính độ dài của list
Độ dài của danh sách đơn giản chỉ là số phần tử trong danh sách đó. Để biết được độ dài của danh sách, chúng ta có thể truy cập thuộc tính length
và sử dụng toán tử .
để truy cập vào bất cứ thuộc tính nào chúng ta muốn.
Syntax như sau:
Hãy xem độ dài của listOfVegetables
là bao nhiêu nhé!
main() {
var listOfVegetables = ['potato', 'carrot', 'cucumber'];
print(listOfVegetables.length);
}
Output: 3
Thêm một phần tử đơn
Chúng ta có thể thêm một phần tử mới vào danh sách hiện tại bằng cách sử dụng phương thức add
. Điều kiện duy nhất là phần tử được thêm phải cùng kiểu với các phần tử đã có trong danh sách.
Phương thức add
có một tham số duy nhất đó chính là phần tử bạn muốn thêm vào danh sách. Kiểu của tham số phụ thuộc vào danh sách mà bạn dùng phương thức gọi vào.
Syntax như sau:
Hãy thêm một loại rau khác vào listOfVegetables
xem sao nhé
main() {
var listOfVegetables = ['potato', 'carrot', 'cucumber'];
listOfVegetables.add('cabbage');
print(listOfVegetables);
}
Output: [potato, carrot, cucumber, cabbage]
Thêm nhiều phần tử
Chúng ta có thể thêm nhiều phần tử mới vào danh sách hiện tại bằng cách sử dụng phương thức addAll
. Tương tự, điều kiện duy nhất là phần tử được thêm phải cùng kiểu với các phần tử đã có trong danh sách.
addAll
cơ bản là gộp các phần tử của hai danh sách lại thành một.
Syntax như sau:
Hãy thêm nhiều loại rau khác vào listOfVegetables
nhé
main() {
var listOfVegetables = ['potato', 'carrot', 'cucumber', 'cabbage'];
listOfVegetables.addAll(['broccoli', 'zucchini']);
print(listOfVegetables);
var vegetablesToAdd = ['okra', 'capsicum'];
listOfVegetables.addAll(vegetablesToAdd);
print(listOfVegetables);
}
Output: [potato, carrot, cucumber, cabbage, broccoli, zucchini]
[potato, carrot, cucumber, cabbage, broccoli, zucchini, okra, capsicum]
Xóa một phần tử đơn
Để xóa một phần tử đơn từ danh sách hiện tại, chúng ta có thể sử dụng phương thức removeAt
. Phương thức removeAt
có một tham số duy nhất đó chính là phần tử bạn muốn xóa khỏi danh sách. Kiểu của tham số đó là int
.
Syntax sẽ như sau:
Hãy xóa một vài loại rau trong listOfVegetables
xem sao nhé:
main() {
var listOfVegetables = ['potato', 'carrot', 'cucumber', 'cabbage', 'broccoli', 'zucchini'];
listOfVegetables.removeAt(0);
print(listOfVegetables);
listOfVegetables.removeAt(2);
print(listOfVegetables);
}
Output:[carrot, cucumber, cabbage, broccoli, zucchini]
[carrot, cucumber, broccoli, zucchini]
Nếu bạn muốn xóa một phần tử những không biết thứ tự của nó thì hãy sử dụng phương thức indexOf
mà chúng ta đã thảo luận ở trên.
Hãy tìm thử thứ tự của “carrot” và xóa nó khỏi listOfVegetables
.
main() {
var listOfVegetables = ['carrot', 'cucumber', 'zucchini'];
var carrotIndex = listOfVegetables.indexOf('carrot');
listOfVegetables.removeAt(carrotIndex);
print(listOfVegetables);
}
Output: [cucumber, zucchini]
Xóa tất cả các phần tử
Để xóa tất cả các phần tử khởi danh sách, chúng ta chỉ cần gọi phương thức clear
. Một phương thức không có tham số nào cả.
Thử xóa tất cả các phần tử của listOfVegetables
main() {
var listOfVegetables = ['cucumber', 'zucchini'];
listOfVegetables.clear();
print(listOfVegetables);
}
Output: []
Phương thức map()
Kiểu List
có một phương thức được biết là map()
, nó khác với collection Map
.
map()
map tất cả các phần tử của list vào một biểu thức hoặc câu lệnh. Ví dụ, chúng ta có thể có một danh sách các số nguyên và chúng ta muốn tính bình phương của mỗi số nguyên trong danh sách. map()
của List được sử dụng để giải quyết những vấn đề như vậy.
Hãy nhìn vào syntax bên dưới:
Iterator có thể là bất cứ cái tên nào. Nó cơ bản là một biến lấy giá trị của từng phần tử một trong danh sách. Iterator bắt đầu lấy phần tử đầu tiên trong danh sách và sau đó sẽ áp dụng phần tử đó vào câu lệnh. Tương tự như vậy cho đến khi không còn phần tử nào để lấy nữa.
Trong ví dụ bên dưới, chúng ta có danh sách các loại rau và chúng ta sẽ in từ “I love vegetable”. Trong đó từ “vegetable” sẽ được thay thế bằng từng phần tử trong list.
main() {
var listOfVegetables = ['carrot', 'cucumber', 'zucchini'];
var mappedVegetables = listOfVegetables.map((vegetable) => 'I love $vegetable');
print(mappedVegetables);
}
Output: (I love carrot, I love cucumber, I love zucchini)
Bạn lưu ý rằng output này chưa phải là một danh sách vì nó không có chứa dấu ngoặc vuông. Để chuyển đổi kết quả của map()
thành một danh sách chúng ta có thể dùng phương thức toList()
Hãy điều chỉnh đoạn code bên trên để output trở thành danh sách nhé.
main() {
var listOfVegetables = ['carrot', 'cucumber', 'zucchini'];
var mappedVegetables = listOfVegetables.map((vegetable) => 'I love $vegetable').toList();
print(mappedVegetables);
}
Output: [I love carrot, I love cucumber, I love zucchini]
4. Cấu trúc dữ liệu set
Trong ngôn ngữ Dart, một set là một tập hợp không theo thứ tự của các phần tử riêng biệt. Điều này có nghĩa là các phần tử đó sẽ không có một vị trí cụ thể ở trong Set. Do đó, một Set sẽ không thể có các bản sao của cùng một phần tử.
4.1 Tạo ra một set
Có rất nhiều cách để tạo ra một set. Hãy tìm hiểu những cách phổ biến nhất ở bên dưới nhé!
Sử dụng literals
Cũng tương tự như list, set cũng có thể được tạo bằng cách khai báo literals. Syntax của list và set cũng khá là giống nhau. Chỉ có một điểm khác biệt đó là trong list sử dụng dấu ngoặc vuông []
trong khi set lại sử dụng dấu ngoặc nhọn {}
.
Cú pháp đơn giản như sau:
Chúng ta bắt đầu với từ khóa var
theo sau là một định danh riêng setName
. Sau đó là dấu =
và các phần tử sẽ nằm bên trong dấu ngoặc nhọn được phân tách bởi dấu ,
Hãy nhìn một ví dụ bên dưới đây.
main() {
var simpleSet = {1,2,3};
print(simpleSet);
}
Output: {1, 2, 3}
Ở dòng var simpleSet = {1,2,3};
của đoạn code ở trên, chúng ta đã khai báo và gán một set với 3 phần tử.
Khi chúng ta sử dụng phương thức print
để in thì output sẽ hiển thị một set hoàn chỉnh với dấu ngoặc nhọn.
Như chúng ta đã thảo luận trước đó, Set không có các phần tử trùng lặp. Tuy nhiên, bạn có thể chèn một bản sao vào trong lúc tạo một set những nó cũng không có hiệu quả gì đâu nhé!
main() {
var simpleSet = {1,2,3,3};
print(simpleSet);
}
Output: {1, 2, 3}
Dart tự suy rằngsimpleSet
có một kiểuSet<int>
, mộtset
với những phần tử kiểuint
.
Nếu bạn muốn chỉ định kiểu dữ liệu khi khai báo, hãy chỉ định trước dấu ngoặc nhọn {
và dùng < >
. Giống như syntax sau đây:
main() {
var setOfNumbers = <num>{1,1.5,2,2.5};
// Driver Code
print(setOfNumbers);
}
Output: {1, 1.5, 2, 2.5}
Tạo ra một Set rỗng bằng cách sử dụng hàm dựng.
Bạn cũng có thể khai báo một set bằng cách sử dụng một hàm dựng set (Set constructor). Một hàm dựng set tạo ra một đối tượng sử dụng dấu ngoặc nhọn {}
.
Có nhiều cách để làm điều đó, hãy xem một vài syntax phổ biến sau đây:
Việc chỉ định kiểu dữ liệu khá là quan trong nếu bạn khai báo một set trống. Nếu chúng ta bỏ qua kiểu dữ liệu, chúng ta sẽ kết thúc bằng map. Chúng ta sẽ thảo luận thêm về map ở phần sau.
Hãy tạo ra một set của trái cây trong ví dụ dưới đây nhé!
main() {
var setOfFruit = <String>{};
print(setOfFruit);
Set<String> anotherSetOfFruit = {};
print(anotherSetOfFruit);
}
Output: {}
{}
Khi chúng ta in setOfFruit
và anotherSetOfFruit
trong đoạn code bên trên, chúng ta sẽ nhận được một set trống (không có phần tử bên trong dấu ngoặc nhọn).
4.2 Làm việc với Set
Cũng tương tự với list, một Set là một kiểu và do đó nó là một đối tượng. Điều này có nghĩa là set cũng có những thuộc tính và phương thức cụ thể.
Thêm một phần tử đơn vào một set
Chúng ta có thể thêm một phần tử đơn vào set hiện tại bằng cách sử dụng phương thức add
. Điều kiện duy nhất là phần tử mà bạn muốn thêm vào phải cùng kiểu với những phần tử khác trong set.
Phương thức add
khi được gọi trên set có một tham số là phần tử mà bạn muốn thêm vào set
. Kiểu của tham số phụ thuộc vào set mà bạn dùng phương thức để gọi vào.
Syntax như sau:
Hãy thêm một vài trái cây khác vào set trái cây của chúng ta nhé!
main() {
var setOfFruit = <String>{};
setOfFruit.add('apples');
setOfFruit.add('bananas');
setOfFruit.add('oranges');
print(setOfFruit);
}
Output: {apples, bananas, oranges}
Bây giờ, setOfFruits
đã có thêm 3 phần tử.
Thêm nhiều phần tử vào set
Chúng ta có thể thêm nhiều phần tử vào set hiện tại bằng cách sử dụng phương thức addAll
. Điều kiện để thêm phần tử vào vẫn là phải cùng kiểu với những phần tử khác trong set.
Phương thức addAll
khi được gọi trên set cũng có một tham số là phần tử mà bạn muốn thêm vào set. Kiểu của tham số đó là Set<dataType>
, kiểu dữ liệu sẽ phụ thuộc vào set mà bạn sử dụng phương thức để gọi vào.
Tóm lại, addAll
cơ bản là gộp các phần tử của 2 set vào thành 1
Syntax sẽ như sau:
Hãy thêm nhiều trái cây vào setOfFruits
nhé!
main() {
var setOfFruits = {'apples', 'bananas', 'oranges'};
var twoMoreFruits = {'watermelon', 'grapes'};
setOfFruits.addAll(twoMoreFruits);
print(setOfFruits);
}
Output: {apples, bananas, oranges, watermelon, grapes}
Trong đoạn code bên trên, chúng ta đã thêm các phần tử twoMoreFruits
vào setOfFruits
.
Tính độ dài của set
Tương tự như list, set cũng có thuộc tính length
Nó sẽ cho bạn biết số lượng phần tử trong một set.
Syntax như sau:
Hãy tính độ dài của setOfFruits
thử nhé!
main() {
var setOfFruits = {'apples', 'bananas', 'oranges', 'watermelon', 'grapes'};
print(setOfFruits.length);
}
Output: 5
Output sẽ hiển thị 5 vì trong setOfFruits
có 5 phần tử.
Hãy thử sao chép một phần tử trong setOfFruits
và xem độ dài của nó là bao nhiêu nhé.
main() {
var setOfFruits = {'apples', 'bananas', 'oranges', 'watermelon', 'grapes', 'apples'};
print(setOfFruits.length);
}
Output: 5
Output vẫn hiện thị là 5 cho dù setOfFruits
có 6 phần tử. Điều này chứng mình rằng Dart hoàn toàn bỏ qua các giá trị trùng lặp trong set.
Xóa các phần tử ra khỏi set
Để xóa một phần tử ra khỏi set, chúng ta sẽ sử dụng phương thức remove
. Phương thức remove
có một tham số đơn là phần tử mà bạn muốn xóa. Kiểu của tham số sẽ tùy thuộc vào set được phương thức gọi vào.
Syntax như sau:
Hãy xóa một vài trái cây từ setOfFruits
nhé!
main() {
var setOfFruits = {'apples', 'bananas', 'oranges', 'watermelon', 'grapes'};
// Remove 'bananas'
setOfFruits.remove('bananas');
print(setOfFruits);
}
Output: {apples, oranges, watermelon, grapes}
Kiểm tra một set
Bạn có thể dùng phương thức contains
và containsAll
để kiểm tra những phần tử cụ thể trong một set. Phương thức contains
sẽ kiểm tra 1 phần tử, phương thức containsAll
sẽ kiểm tra nhiều phần tử.
Syntax cho phương thức contains
:
Syntax cho phương thức containsAll
Hãy xem một ví dụ bên dưới:
main() {
var setOfFruits = {'apples', 'oranges', 'watermelon', 'grapes'};
//Check whether a single item is in the set
print(setOfFruits.contains('grapes'));
//Check whether multiple items are in the set
print(setOfFruits.containsAll(['watermelon', 'bananas'])); //First Method
var fruitsToCheck = {'watermelon', 'bananas'};
print(setOfFruits.containsAll(fruitsToCheck)); // Second Method
}
Output: true
false
false
Output thứ nhất là true
bởi vì “grapes” là một phần của setOfFruits
. Output thứ hai hiển thị false
vì “bananas” không có trong setOfFruits
, cho dù có “watermelon”.
Phép giao giữa 2 set
Phần giao nhau giữa 2 set (set1, set2) là một set chứa các phần tử có ở cả set1 và set2.
Syntax như sau:
Hãy nhìn vào ví dụ bên dưới:
main() {
var setOfFruits = {'apples', 'oranges', 'watermelon', 'grapes'};
var setOfMoreFruits = {'oranges', 'kiwi', 'bananas'};
var intersectionSet = setOfFruits.intersection(setOfMoreFruits);
print(intersectionSet);
}
Output: {oranges}
Output sẽ hiển thị một set có 1 phần tử là “orange” bởi vì phần tử này có ở cả setOfFruits
và SetOfMoreFruits
Phép hợp giữa 2 set
Phần hợp giữa 2 set là một set chứa tất cả các phần tử của 2 set đó. Trong đó, mỗi phần tử chỉ xuất hiện một lần.
Syntax như sau:
Hãy điều chỉnh một chút đoạn code ở ví dụ bên trên để có được kết quả phần hợp của 2 set nhé.
main() {
var setOfFruits = {'apples', 'oranges', 'watermelon', 'grapes'};
var setOfMoreFruits = {'oranges', 'kiwi', 'bananas'};
var intersectionSet = setOfFruits.union(setOfMoreFruits);
print(intersectionSet);
}
Output: {apples, oranges, watermelon, grapes, kiwi, bananas}
5. Maps, Keys, Values
Một map là một collection không theo thứ tự của cặp key/value. Nó liên kết key với Value và mỗi value đều có một key. Điều này có nghĩa là mỗi key phải riêng biệt, tuy nhiên value của các phần tử có thể giống nhau. Hai phần tử mặc dù có value giống nhau nhưng vẫn là hai phần tử riêng biệt thông qua key riêng của chúng.
Sử dụng map khi bạn cần truy cập đối tượng bằng định danh riêng.
5.1 Tạo ra một Map
Có nhiều cách để tạo ra một map. Hãy tìm hiểu một vài cách phổ biến bên dưới đây nhé.
Sử dụng Literals
Tương tự như list và set, map cũng có thể được tạo ra bằng cách sử dụng literal. Nó hơi phức tạp một chút so với những gì mà chúng ta từng biết cho đến bây giờ.
Syntax như sau:
Syntax ban đầu khá giống với syntax của list literal và set literal. Điều thú vị chỉ xảy ra sau dấu ngoặc nhọn mở {
. Mỗi cặp key/value được viết trên từng dòng. Đối với mỗi cặp key/value được phân tách bằng dấu hai chấm (:
). Sau cặp key/value cuối cùng, chúng ta chuyển sang dòng tiếp theo và chèn dấu ngoặc nhọn đóng (}
).
Nếu muốn, bạn có thể thêm dấu phẩy (,
) sau cặp key/value cuối cùng. Điều này sẽ không gây ra lỗi, cũng không ảnh hưởng đến chức năng.
Chúng ta sẽ tạo một map để truy vấn thủ đô của các quốc gia. Trong ví dụ này, Key sẽ là quốc gia và Value sẽ là thủ đô của quốc gia đó.
main() {
var capitals = {
'United States' : 'Washington D.C.',
'England' : 'London',
'China' : 'Beijing',
'Germany' : 'Berlin',
'Nigeria' : 'Abuja',
'Egypt' : 'Cairo',
'New Zealand' : 'Wellington'
};
// Driver Code
print(capitals);
}
Output: {United States: Washington D.C., England: London, China: Beijing, Germany: Berlin, Nigeria: Abuja, Egypt: Cairo, New Zealand: Wellington}
Dart tự suycapitals
là kiểuMap<String,String>
Sử dụng hàm dựng
Bạn cũng có thể tạo ra một map bằng cách sử dụng hàm dựng Map. Syntax cơ bản của nó cũng giống như hàm dựng List.
main() {
var emptyMap = Map();
// Driver Code
print(emptyMap);
}
Output: {}
Sử dụng kiểu chỉ định
Map là những kiểu được tham số hóa. Điều này có nghĩa là bạn có thể chỉ định kiểu cho key và value.
Syntax như sau:
Kiểu dữ liệu của key có thể khác với kiểu của value.
Trong ví dụ bên dưới, key có kiểu là int
và value có kiểu là String
.
main() {
var numbers = Map<int, String>();
print(numbers);
}
Output: {}
5.2 Làm việc với Maps
Tương tự như lists và sets, maps là những đối tượng có các thuộc tính và phương thức. Hãy tìm hiểu chúng ở phần bên dưới nhé.
Thêm cặp key/value
Để thêm một cặp key/value mới , hãy sử dụng syntax sau:
Hãy thêm một vài cặp key/value vào map numbers
của bài học trước nhé
main() {
var numbers = Map<int, String>();
numbers[1] = 'one';
numbers[2] = 'two';
numbers[3] = 'three';
print(numbers);
}
Output: {1: one, 2: two, 3: three}
Tính số lượng cặp trong Maps
Như chúng ta đã thảo luận trong lists và sets, Map
cũng có thuộc tính length
để tính số lượng cặp key-value có trong map
Syntax như sau:
Hãy tính độ dài của numbers
main() {
var numbers = {
1 : 'one',
2 : 'two',
3 : 'three'
};
print(numbers.length);
}
Output: 3
Truy vấn một Value
Bằng cách cung cấp một Key bên trong dấu ngoặc vuông []
, bạn có thể truy vấn được một Value tương ứng.
Syntax như sau:
Hãy truy vấn một giá trị từ map capitals
main() {
var capitals = {
'United States' : 'Washington D.C.',
'England' : 'London',
'China' : 'Beijing',
'Germany' : 'Berlin',
'Nigeria' : 'Abuja',
'Egypt' : 'Cairo',
'New Zealand' : 'Wellington'
};
print(capitals['Germany']);
}
Output: Berlin
Trong đoạn code trên, chúng ta muốn lấy lại giá trị liên kết với key Germany
và khi in output hiển thị Berlin
Nếu như key không tồn tại thì bạn sẽ nhận được output là null
main() {
var capitals = {
'United States' : 'Washington D.C.',
'England' : 'London',
'China' : 'Beijing',
'Germany' : 'Berlin',
'Nigeria' : 'Abuja',
'Egypt' : 'Cairo',
'New Zealand' : 'Wellington'
};
print(capitals['India']);
}
Output: null
Kiểm tra một key
Bạn có thể kiểm tra liệu map đó có chứa key bạn muốn hay không bằng cách sử dụng phương thức containsKey
Syntax như sau:
Nếu key tồn tại, phương thức sẽ trả lại kết quả là true
, nếu không thì sẽ trả kết quả false
.
Truy xuất tất cả keys và values
Map
có thuộc tính keys
và values
có thể được sử dụng để truy cập tất cả các keys và values của một map cụ thể.
Syntax như sau:
Hãy xuất tất tất cả các keys và values của capitals
main() {
var capitals = {
'United States' : 'Washington D.C.',
'England' : 'London',
'China' : 'Beijing',
'Germany' : 'Berlin',
'Nigeria' : 'Abuja',
'Egypt' : 'Cairo',
'New Zealand' : 'Wellington'
};
// Retrieving all the keys
var allKeys = capitals.keys;
print("Keys: $allKeys");
// Retrieving all the values
var allValues = capitals.values;
print("Values: $allValues");
}
Output:
Keys: (United States, England, China, Germany, Nigeria, Egypt, New Zealand)
Values: (Washington D.C., London, Beijing, Berlin, Abuja, Cairo, Wellington)
Xóa một cặp Key/Value
Phương thức remove
có thể được sử dụng để xóa một cặp key/value trong map. Tham số mà bạn muốn chuyền qua phương thức chính là key trong cặp key/value mà bạn muốn xóa khỏi map.
Syntax như sau:
Hãy xóa một cặp Key/Value từ capitals
main() {
var capitals = {
'United States' : 'Washington D.C.',
'England' : 'London',
'China' : 'Beijing',
'Germany' : 'Berlin',
'Nigeria' : 'Abuja',
'Egypt' : 'Cairo',
'New Zealand' : 'Wellington'
};
// Removing a key-value pair
capitals.remove('China');
print(capitals);
}
Output:
{United States: Washington D.C., England: London, Germany: Berlin, Nigeria: Abuja, Egypt: Cairo, New Zealand: Wellington}
Map được điều chỉnh sẽ không còn cặp 'China': 'Beijing'
nữa.
Kết thúc bài viết về collection của series, chúng ta hãy tìm hiểu về "Control Flow Statements" trong bài viết tiếp theo nhé!
Bài viết liên quan
Tự học Dart: Các Dart Operators (toán tử) bạn cần biết
Sep 02, 2023 • 18 min read
Flutter cơ bản: Điều cần biết khi lập trình ứng dụng đầu tiên
Aug 23, 2023 • 13 min read
Dart là gì? Giới thiệu cơ bản về ngôn ngữ lập trình Dart
Aug 21, 2023 • 11 min read
Flutter là gì? Vì sao nên học công cụ lập trình Flutter?
Aug 19, 2023 • 11 min read
Flutter cơ bản: Widget Tree, Element Tree & Render Tree
Aug 19, 2023 • 10 min read
So sánh StatelessWidget và StatefulWidget
Jul 17, 2022 • 12 min read