// React
array.map(e, index) => ...
// Vue
<div v-for="(item,index) in items"></div>
React나 Vue에선 이런 형태로 반복문에서 바로 배열의 index에 접근할 수 있었지만(공식문서에서 추천하는 방식은 아님)
Flutter가 사용하는 Dart 언어에선 List.map에서 따로 index를 지원해 주지 않는다.
그럼에도 index에 접근해야한다면 어떻게 해야할까?
List<String> colors=['red', 'yellow', 'blue'];
var colors2 = List.generate(colors.length, (i) => Text(child: colors[i]);
// [Text(child: 'red'), Text(child: 'yellow'), Text(child: 'blue')]
List의 내장 메서드로 (int, callback)을 인자로 받아 callback 함수를 int 횟수 반복한 값으로 List를 만들어 준다. 이를 통해 List[index]의 형태로 접근 할 수 있다.
*개인적으로 생각하는 장점은 길이를 List.length에 의존하지 않고 마음대로 커스텀 할 수 있다는 점과 toList()를 붙여주지 않아도 된다는 점. 그리고 보통 index에 접근한다는 건 index를 통해 다른 작업을 해주기 위함인데 callback 함수가 복잡해졌을 때 가독성이 좋은 편이라는 점이 있다.
{bool growable = true}
추가) 추가 파라미터로 growable을 받는데, false를 넣어주면 크기가 고정된 List를 반환한다.
공식문서 참조 https://api.flutter.dev/flutter/dart-core/List/List.generate.html
이건 우선 공식문서를 보고 오자
공식문서 참조 https://api.flutter.dev/flutter/dart-core/List/asMap.html
List를 Map {index: value}의 형태로 반환해준다고 한다.
List<String> colors=['red', 'yellow', 'blue'];
var colors2 = colors.asMap().entries.map((e) => ...).toList();
// {0: 'red', 1: 'yellow', 2: 'blue'}
// colors[e.key] == e.value
Map을 다루 듯이 다뤄주면 되는데, 일반적으로 사용하는 형태를 적어보았다. .entries.map 대신 .forEach를 사용해도 되고 이외에도 .keys, .values, .containsKey 등등 모두 활용 가능하다.
*개인적으로 생각하는 장점은 .map() 앞에 asMap.entries만 붙여주면 된다는 점(기존에 사용하던 패턴을 수정하기 용이)
extension MapWithIndex<T> on List<T> {
List<R> mapWithIndex<R>(R Function(T, int i) callback) {
List<R> result = [];
for (int i = 0; i < this.length; i++) {
R item = callback(this[i], i);
result.add(item);
}
return result;
}
}
// colors.mapWithIndex((e, i) => ...);
// colors[i] == e;
동료 Gavri의 코드를 가져옴.
Dart 2.7 버전부터 지원하는 extension 키워드를 통해 기존 제네릭타입을 확장할 수 있는데, callback 함수를 통해 원하는 타입의 return값을 배열로 받을 수 있다. 위에 예시의 React의 map과 가장 유사한 형태.
틀린 부분이나 추가했으면 하는 내용을 댓글로 알려주세요!