(썸네일 출처: unsplash)
A collection of values, or "elements", that can be accessed sequentially.
- Element 혹은 Value 로 구성된 Collection 인데, 순차적으로 접근이 가능한 Collection 을 Iterable 이라고 합니다.
Iterable 하기 위해서는 "Iterator" 를 이용해서 순회가 가능합니다. Iterator 를 통해서 다음으로 넘어가거나 해당하는 값에 접근하게 됩니다.
Iterator 클래스를 보면, 다음과 같은 동작들을 할 수 있습니다.
Current -> E
: 현재 값에 접근할 수 있음.moveNext() -> bool
: 다음 값으로 넘어감.iterator.current
를 사용할 것!)간단하게 코드를 보면, 다음과 같습니다.
var it = obj.iterator;
while (it.moveNext()) {
use(it.current);
}
moveNext()
메소드를 통해 순회하고 있습니다. 그리고 Iterator 내부에 있는 current
라는 Element 를 리턴하는 프로퍼티를 이용해 값을 사용하고 있습니다.우리가 자주 사용하는 Collection 중에서 Map 에서 "key" 가 Iterable 을 따르고 있습니다. 그래서 다음과 같은 코드로 순회가 가능하게 되는 거죠.
void main() {
var menuList = {
'모히또': '몰디브',
'찜닭': '안동',
'잣호두과자': '가평 휴게소',
'짬뽕순두부': '동화가든',
};
for (var menu in menuList.keys) {
print("$menu 에서 유명한 메뉴는 ${menuList[menu]} 입니다.");
}
}
(DartPad 에서 실행)
결과
모히또 에서 유명한 메뉴는 몰디브 입니다.
찜닭 에서 유명한 메뉴는 안동 입니다.
잣호두과자 에서 유명한 메뉴는 가평 휴게소 입니다.
짬뽕순두부 에서 유명한 메뉴는 동화가든 입니다.
위 예시에서는 Map 클래스의 key 속성을 예시로 들었지만, List
, Set
모두 Iterable 을 따르고 있습니다. dart:collection
에 있는 라이브러리는 거의 따른다고 보면 됩니다.
cf) dart:collection
Swift Sequence 글에서도 작성했다시피, Iterable
를 따른다고 해서, 배열처럼 Random Access
기능이 추가되는 것은 아닙니다. 오직 "순차적으로" + "한번에 하나씩" 에 초점이 맞춰진 추상클래스 입니다.
다만 Swift 와 다른 점은 Iterator
임에도 index Access 가 가능하도록 메소드가 구현되어 있습니다.
E elementAt(int)
E elementAt(int index) {
// 입력된 인자가 음수인지 확인합니다.
RangeError.checkNotNegative(index, "index");
// 임시값 역할의 프로퍼티
int elementIndex = 0;
for (E element in this) {
// 입력받은 인덱스랑 동일해지는 시점에 해당 값을 리턴합니다.
if (index == elementIndex) return element;
// 만약 인덱스가 다르면, 다시 순환합니다.(Iterating)
elementIndex++;
}
// 모두 해당하지 않는다면, Error 를 리턴합니다.
throw RangeError.index(index, this, "index", null, elementIndex);
}
Iterable<int> iterable = [1, 2, 3];
void main() {
int value = iterable.elementAt(1);
print(value); // print Result : 2
}