Iterable collections Dart 문서 읽기
Collection과 Iterable
-
Collection : element의 집합을 표현하는 객체 (e.g.
List
,Set
,Map
) -
Iterable : element에 순차적으로 접근할 수 있는 collection의 한 종류
-
Iterable
abstract class를 상속받은List
,Set
등을 통해Iterable
객체 생성 -
Map
은 key를 사용해서 value를 얻는 방식으로Iterable
이 아님. 단,entries
나values
속성을 통해 key 또는 value group을Iterable
객체로 읽을 수 있음 -
Iterable
과List
는 element에 접근하는 방법에 차이가 있음-
List
는[index]
operator를 사용하지만,Iterable
은elementAt(index)
method를 사용해서 특정 index의 element에 접근Iterable<int> iterable = [1, 2, 3]; print(iterable.elementAt(1)); // 2 List<int> list = [1, 2, 3]; print(list[1]); // 2
-
elementAt()
은index
까지 다른 element들을 무시함 (step through)
-
-
Reading elements
for-in
loop :Iterable
을 순회하며 element 읽기const iterable = ["Salad", "popcorn"]; for (final element in iterable) { print(element); }
first
andlast
:Iterable
의 첫 번째 또는 마지막 element 읽기Iterable<String> iterable = const ["Salad", "Popcorn", "Toast"]; iterable.first; // Salad iterable.last; // Toast
- Empty
Iterable
에서 사용하면StateError
발생
- Empty
firstWhere(predicate)
: 특정 조건을 만족하는 첫 번째 element 읽기const items = ["Salad", "Popcorn", "Toast", "Lasagne"]; final element = iterable.firstWhere( (element) => element.length > 5, orElse: () => "None!", ); print(element); // Popcorn
predicate
함수에서 조건을 검사하여true
를 반환하는 첫 번째 element 반환- 조건에 만족하는 element를 찾지 못하면,
StateError
발생orElse
함수를 전달하면 이 함수가 반환하는 값을 반환
singleWhere(predicate)
: 특정 조건을 단 한번만 만족하는 element 읽기const items = ["Salad", "Popcorn", "Milk", "Toast", "Lasagne"]; final element = items.singleWhere( (element) => element.startsWith("M") && element.contains("a"), ); print(element); // Milk
firstWhere()
는 조건에 맞는 element를 찾으면 종료singleWhere()
는Iterable
의 모든 element를 순회하므로 infinite 또는 element가 아주 많은Iterable
에서 사용하면StateError
가 발생할 수 있음
Checking conditions
every(predicate)
: 모든 element가predicate
조건을 만족할 때true
반환final isValid = items.every((item) => item.length >= 5);
any()
:predicate
조건을 만족하는 element가 최소 1개 이상일 때true
반환const items = ["Salad", "Popcorn", "Toast"]; final any = items.any((item) => item.contains("a")); // true (Salad or Toast) final every = items.every((item) => item.length >= 5); //
any()
는 조건을 만족하는 element가 1개라도 있으면true
를 반환any()
를 조건을 만족하는 element가 없다는 것을 검증할 때도 사용 가능 (false
를 반환하는 경우)
Filtering elements
where()
: 특정 조건을 만족하는 모든 element를 찾아서 새Iterable
(WhereIterable
)로 만들어 반환final evenNumbers = numbers.where((number) => number.isEven);
firstWhere()
나singleWhere()
는 조건을 만족하는 element 1개를 찾는다는 차이가 있다.- 조건에 맞는 element가 없다면 empty
Iterable
반환 (firstWhere()
와 달리StateError
를 발생시키지 않음)
takeWhile(predicate)
:predicate
에서false
를 반환하기 이전 element들을 모아서 새Iterable
로 반환const numbers = [1, 3, -2, 0, 4, 5]; final numbersUntilZero = numbers.takeWhile((number) => number != 0); print(numbersUntilZero); // [1, 3, -2]
skipWhile()
:predicate
에서false
를 반환한 이후 element들을 모아서 새Iterable
로 반환const numbers = [1, 3, -2, 0, 4, 5]; final numbersUntilZero = numbers.skipWhile((number) => number != 0); print(numbersUntilZero); // [0, 4, 5]
predicate
에서false
를 반환하는 element를 찾으면 이후 element에 대해서는 조건을 검사하지 않음
Mapping elements
map()
:Iterable
의 각 element들을 새로운 값으로 교체Iterable<int> output = numbers.map((number) => number * 10);
Other APIs
문서에서 소개한 함수 외에 Iterable
객체에서 사용할 수 있는 유용한 함수들
fold()
const items = ["Salad", "Popcorn", "Milk", "Toast", "Lasagne"];
final count = items.fold(0, (previous, element) => previous + element.length);
print(count); // 28 = 5 + 7 + 4 + 5 + 7
- collection의 element들을
initialValue
와 연산하여 하나의 값으로 합침 - 다른 언어의 reduce 함수
reduce()
const items = [1, 2, 3];
final sum = items.reduce((value, element) => value + element);
print(sum); // 6
fold
와 같은 역할이지만,initialValue
없이 collection의 element들을 가지고 연산- 다른 언어의 reduce와 달리 결과 type이 원본 collection type으로 고정되어 있음
- Collection이 비어있다면
IterableElementError
발생
forEach()
const items = ["Salad", "Popcorn", "Toast"];
items.forEach(print); // Salad, Popcorn, Toast
- 각 element들에 대해 함수 실행
join()
const numbers = [1, 2, 3];
final result = numbers.join("-");
print(result); // 1-2-3
- Element를
String
type으로 변환한 뒤separator
로 연결(concatenate)
contains()
const items = ["Salad", "Popcorn", "Toast"];
items.contains("Toast"); // true
items.contains("Milk"); // false
Iterable
에element
가 들어 있는지 판단- Dart의 모든 값은 객체이므로
Object
type parameter로 전달 가능
take(count)
const items = ["Salad", "Popcorn", "Milk", "Toast", "Lasagne"];
final result = items.take(3);
print(result); // [Salad, Popcorn, Milk]
Iterable
의 element들 중 처음count
개의 element를 모아서 lazy iterable 생성- 내부적으로 iterator가
count
개의 element를 읽은 후에야 iterable을 생성
skip(count)
const items = ["Salad", "Popcorn", "Milk", "Toast", "Lasagne"];
final result = items.skip(3);
print(result); // [Toast, Lasagne]
Iterable
의 element들 중 처음count
개의 element를 제외한 나머지 element들을 모아서 iterable 생성