Dart - Iterable이란?

Uno·2022년 12월 22일
0

dart

목록 보기
3/7
post-thumbnail

(썸네일 출처: unsplash)

Iterable 이란?

A collection of values, or "elements", that can be accessed sequentially.

  • Element 혹은 Value 로 구성된 Collection 인데, 순차적으로 접근이 가능한 Collection 을 Iterable 이라고 합니다.

Iterable 하기 위해서는 "Iterator" 를 이용해서 순회가 가능합니다. Iterator 를 통해서 다음으로 넘어가거나 해당하는 값에 접근하게 됩니다.

Iterator 클래스를 보면, 다음과 같은 동작들을 할 수 있습니다.

  • Current -> E : 현재 값에 접근할 수 있음.
  • moveNext() -> bool : 다음 값으로 넘어감.
    - true 가 리턴되면, 다음으로 넘어갑니다.
    (만약 값에 접근에 희망하면 iterator.current 를 사용할 것!)
    - false 가 리턴되면, 다음 값이 없으므로 순회도 멈춥니다.
    (참고로, 에러를 리턴하거나 false 를 리턴한 이후에 iterator 에 접근해서 값에 접근하면(current) 임의의 값에 접근할 수 있다고 합니다.)

예시

간단하게 코드를 보면, 다음과 같습니다.

var it = obj.iterator;
while (it.moveNext()) {
	use(it.current);
}
  • iterator 내부에 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

  • Map
  • Set
  • Queue
  • List
  • LinkedList

배열과의 차이점

Swift Sequence 글에서도 작성했다시피, Iterable 를 따른다고 해서, 배열처럼 Random Access 기능이 추가되는 것은 아닙니다. 오직 "순차적으로" + "한번에 하나씩" 에 초점이 맞춰진 추상클래스 입니다.

다만 Swift 와 다른 점은 Iterator 임에도 index Access 가 가능하도록 메소드가 구현되어 있습니다.

  • Iterable 하위에 있는 메소드 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
}

참고자료

profile
iOS & Flutter

0개의 댓글