mapWithIndex와 친구들
인덱스를 아는 네 연산자 — map, filter, flatMap, fold가 원소의 위치를 두 번째 인자로 받습니다.
강의
위치를 얻는 방법은 이미 있었습니다.
zipWithIndex로 원소마다
인덱스를 짝지은 뒤 그 쌍을 읽으면 됩니다. 쌍 자체가 필요할 때는 그게
맞는 도구입니다. 그렇지 않을 때는 원소마다 레코드 하나를 치르고,
콜백 본문을 이름 대신 p.$1 / p.$2로 쓰게 됩니다.
이 넷은 인덱스를 곧바로 받습니다. 할당할 것도, 꺼낼 것도 없고, 체인이 하는 일이 그대로 읽힙니다.
인덱스는 그 단계의 입력을 셉니다. 원본에서의 위치가
아닙니다 — filter가
mapWithIndex 위에 있으면 살아남은 값들이
0부터 다시 매겨집니다. 두 번 읽어야 할 쪽은
filterWithIndex입니다. 버리는 원소도 입력이므로
그만큼 카운트가 올라갑니다. flatMapWithIndex는 내보낸 값이
아니라 소스 원소를 세므로, 안쪽 이터러블이 다섯 개를 내놓아도 인덱스는
하나만 올라갑니다.
넷 모두 …Async 형태가 있고, 번호는
concurrent 아래에서도
유지됩니다. 상류 pull은 겹쳐 실행되지만 해소는 여전히 순서대로 되므로,
지연 시간이 어떻든 n번째 원소는 인덱스 n을 받습니다.
카운터는 이터러블이 아니라 순회마다 살아 있어서, 체인을 다시
돌리면 0부터 다시 시작합니다.
foldWithIndex에는 Dart 쪽 주름이 하나 있습니다. 누산기
람다에 타입을 적지 않으면 Acc가 Object?로
추론되어 산술이 컴파일되지 않습니다. 여기서 새로 생긴 문제는 아니고 —
Dart의 Iterable.fold도 똑같습니다 — 해법도 같습니다.
foldWithIndex<int>(…)라고 적으면 됩니다.
데모 1 · mapWithIndex, 그리고 무엇을 대신하는가
데모 2 · filter, flatMap, fold — 그리고 비동기
직접 해 보기
연습: 인덱스를 써서 완주자를 1st, 2nd, 3rd로 매겨 보세요.