Iterator trong Dart là gì?
Iterator trong Dart là một tập hợp các giá trị, hoặc “phần tử”, có thể được truy cập tuần tự. Nói cách khác lớp Iterator
bao gồm các đối tượng có thể duyệt (Iterable) tuần tự, tức là cho phép ta lấy từng phần tử của nó, hành động này có thể được lặp đi lặp lại. Ví dụ, List
và Set
đều là các Iterable
Iterator/ Iterable có thể hiểu nôm na là kiểu “liệt kê”, sử dụng để liệt kê tuần tự các phần tử.
Trong Dart, một Iterator/
là một lớp trừu tượng, có nghĩa là bạn không thể khởi tạo trực tiếp nó. Tuy nhiên, bạn có thể tạo mới Iterable
Iterable
bằng cách tạo mới một danh sáchList
hoặc tập hợp Set
.
void main() { var iterable = ['Salad', 'Popcorn', 'Toast']; for (var element in iterable) { print(element); } }
Trong ví dụ trên thì biến iterable
chính là một List
, chúng ta sử dụng từ khóa var
nên Dart sẽ tự nhận dạng kiểu dữ liệu cho chúng ta. Để tạo một Iterator
, chúng ta chỉ có cách sử dụng phương thức iterator
đối với các biến thuộc kiểu List
, Set
…
Truy cập các phần tử của lớp Iterator
Với lớp Iterator
, bạn không thể truy cập trực tiếp các phần tử như lớp List
mà phải lần lượt duyệt qua tất cả các phần tử phía trước. Thay vào đó, bạn có thể đọc các phần tử với elementAt()
bằng cách duyệt lần lượt qua các phần tử của nó cho đến khi nó đạt đến vị trí đó.
Chính vì lí do đó, bạn không thể gọi iterable[0]
để truy cập phần tử đầu tiên của biến iterable
mà phải sử dụng thuộc tính first
, lấy phần tử đầu tiên. Tương tự, bạn không thể sử dụng toán tử []
để truy cập phần tử cuối cùng, nhưng bạn có thể sử dụng thuộc tính last
.
void main() { Iterable numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; int value = numbers.elementAt(3); print(value); //kết quả 3 print('The first value is ${numbers.first}');//kết quả 0 print('The last value is ${numbers.last}');//kết quả 10 }
Lưu ý, việc truy cập phần tử cuối cùng của một
Iterator
yêu cầu phải duyệt qua tất cả các phần tử khác nên có thể rất chậm.
Để duyệt qua các phần tử của một Iterator
, bạn có thể sử dụng vòng lặp for
.
Các thuộc tính và phương thức của kiểu Iterator trong Dart
current
trả về phần tử hiện tại của mộtIterator
moveNext()
trả vềtrue
nếu phần tử hiện tại chưa phải phần tử cuối cùng đồng thời đặt phần tửcurrent
là phần tử tiếp theo, trả vềfalse
nếu phần tử hiện tại đang là phần tử cuối cùng của mộtIterator
và đặtiterator.currrent = null
firstWhere()
để tìm phần tử đầu tiên thỏa mãn các điều kiện nhất địnhsingleWhere()
có thể giúp bạn tìm một phần tử thỏa mãn một vị từ nhất địnhwhere()
sử dụng để tìm tất cả các phần tử thỏa mãn một điều kiện nào đóany()
: Trả về true nếu có ít nhất một phần tử thỏa mãn điều kiện.every()
: Trả về true nếu tất cả các phần tử thỏa mãn điều kiện.
Duyệt qua các phần tử của List
bằng vòng lặp for
void main(){ //list var myList = [25, 63, 84]; //traverse through each element of list for(var i=0;i<myList.length;i++){ print(myList[i]); } }
hoặc sử dụng phương thức forEach()
của kiểu List
void main(){ var myList = [24, 63, 84]; myList.forEach((element) => print(element) ); }
hoặc chuyển List
sang Iterator
và sử dụng vòng lặp while
void main(){ //list var myList = [25, 63, 84]; //get iterator to the list var myListIter = myList.iterator; //iterate over the list while(myListIter.moveNext()){ print(myListIter.current); } }
Kiểu Map
không phải là một đối tượng Iterable
, tuy nhiên bạn có thể duyệt qua từng phần tử của Map
bằng các sử dụng thuộc tính key
và value
của nó.
void main() { Map kidsBooks = { 'Matilda': 'Roald Dahl', 'Green Eggs and Ham': 'Dr Seuss', 'Where the Wild Things Are': 'Maurice Sendak' }; for (var book in kidsBooks.keys) { print('$book was written by ${kidsBooks[book]}'); } }
Khi chạy chương trình, chúng ta được kết quả như hình sau:
Bạn có thể xem thêm tại https://dart.dev/codelabs/iterables