Facebook Pixel

Tự học ngôn ngữ Dart: Collection của ngôn ngữ Dart

07 Jul, 2021

Nguyên

Author

Tự học ngôn ngữ Dart. Collection là gì? Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu về collection trong ngôn ngữ Dart.

Tự học ngôn ngữ Dart: Collection của ngôn ngữ Dart

Mục Lục

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.

Cách hàm hoạt động - function

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.

Dart
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 objectNamearguments 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
Dart
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 Map.

collections trong ngôn ngữ Dart

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:

list

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.

Dart
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ằng List 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ự suy simpleList là một kiểu List<int> (một List với những phần tử kiểu int)

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é!

Dart
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é!

Dart
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.

indexing

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.

indexing

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:

index

Xem ví dụ bên dưới:

Bash
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é!

Dart
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é

Dart
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é

Dart
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:

Xóa một phần tử đơn

Hãy xóa một vài loại rau trong listOfVegetables xem sao nhé:

Dart
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.

Dart
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

Dart
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.

Dart
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é.

Dart
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:

set

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.

Dart
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é!

Dart
main() {
  var simpleSet = {1,2,3,3};

  print(simpleSet);
}

Output: {1, 2, 3}

Dart tự suy rằng simpleSet có một kiểu Set<int>, một set với những phần tử kiểu int.

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:

chỉ định kiểu dữ liệu
Dart
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:

Tạo ra một Set rỗng bằng cách sử dụng hàm dựng.

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é!

Dart
main() {
  var setOfFruit = <String>{};
  print(setOfFruit);

  Set<String> anotherSetOfFruit = {};
  print(anotherSetOfFruit);
}

Output:
{}
{}

Khi chúng ta in setOfFruitanotherSetOfFruit 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:

Thêm một phần tử đơn vào một set

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é!

Dart
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é!

Dart
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é!

Dart
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é.

Dart
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é!

Dart
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 containscontainsAll để 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:

Dart
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ả set1set2.

Syntax như sau:

Phép giao giữa 2 set

Hãy nhìn vào ví dụ bên dưới:

Dart
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ả setOfFruitsSetOfMoreFruits

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:

Phép hợp giữa 2 set

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é.

Dart
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:

Tạo ra một map

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 đó.

Dart
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ự suy capitals là kiểu Map<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.

hàm dựng Map
Dart
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.

Dart
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:

key/value

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é

Dart
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:

mapName.length

Hãy tính độ dài của numbers

Dart
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:

mapName[key]

Hãy truy vấn một giá trị từ map capitals

Dart
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

Dart
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:

containsKey

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 keysvalues 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

Dart
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");  
}
Bash
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:

Phương thức remove

Hãy xóa một cặp Key/Value từ capitals

Dart
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);  
}
Bash
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

Lập trình backend expressjs

xây dựng hệ thống microservices
  • Kiến trúc Hexagonal và ứng dụngal font-
  • TypeScript: OOP và nguyên lý SOLIDal font-
  • Event-Driven Architecture, Queue & PubSubal font-
  • Basic scalable System Designal font-

Đăng ký nhận thông báo

Đừng bỏ lỡ những bài viết thú vị từ 200Lab