파파비의 블로그

플러터, flutter & Dart) iterable & .map function & spread operator(...) 본문

개발/flutter

플러터, flutter & Dart) iterable & .map function & spread operator(...)

N. Dave 2020. 5. 24. 20:58
반응형

Dart에서는 iterable이라는 개념이 있다.

이것은 반복이 가능한...집단 이란 뜻으로,

list나 array, 등을 의미한다. Map은 iterable이 아니다. 왜냐면 순서가 없으니까.

하지만 linked Map은 순서가 있으니 iterable이다.

 

(자료구조를 알면 좀 더 명확히 될 것이다. iterable은 for처럼 한바퀴돌릴 수 있는 자료구조를 얘기한다,

array나 linked Map은 다음 data의 위치를 알 수 있어서 iterable 하지만,

Map의 경우 Key-value 구조이기 때문에 순환(iterate)하는게 불가능하다)

 

 

iterable 뜻

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

(출처 : https://api.flutter.dev/flutter/dart-core/Iterable-class.html)

= collection 이고,  순서가 있어야한다. (sequentially)

 

iterable에는 map이라는 메소드가 존재한다.

map의 인자는 fuction이다.

map메소드는 해당 iterable의 요소들을 순서대로 훑으면서 map안에 넣어진 fuction을 돌린다.

map 안에 넣어진 fuction은 iterable의 요소를 인자로 갖는다.

 

한마디로 쉽게 말하면 map 메소드는 iterable를 대상으로 foreach을 한 번 돌려주는 것이다.

안에 넣어진 함수는 return으로 '하나'의 widget(flutter가 아닌 곳에선 어떤 객체) 을 내 놔야한다. 

인자로 iterable의 하나의 요소를 받기 떄문이다.

map 메소드가 실행되면 iterable의 요소수만큼 함수가 호출된다.

 

그리고 아무것도 return 안하는 작업은 안된다.

그 모든 return 값들(플러터에선 생성된 widget들)을 모아서 새로운 iterable로 return시킨다.

그래서 종종 .tolist 를 뒤에 붙여서 리스트로 값을 받기도 한다.

 

 

 

해당 코드를 보자. 해석을 해보자면

 

question[_questionIndex]['answer] as List<String>

=> question[_questionIndex]['answer]의 값이 List<String>이다. 그런데 dart에서 인식을 못해서

as List<String> 을 추가로 해주었다.

 

=> List<String>은 iterable이다. 순서도 있고 collection이다. 따라서 .map을 사용할 수 있다.

 

.map((e) => Answer( buttonText : e, callbackFunc: changeQuestion,)).toList()

=> List<String>에 .map()을 실행했다.

 - 한마디로 question[_questionIndex]['answer]의 요소들을 foreach처럼 쭉 돌리면서 

map()의 인자로 넣어진 함수를 돌리겠다는 뜻이다.

 

=> (e) => Answer( buttonText : e, callbackFunc: changeQuestion,)

 - map에 넣어진 함수이다. 이중에서 e는 question[_questionIndex]['answer]의 요소를 의미한다.

 - 그리고 함수의 return은 Answer라는 위젯이다. 요소 하나당 하나의 Answer위젯이 탄생한다.

 

=> Answer( buttonText : e, callbackFunc: changeQuestion,), 

 - question[_questionIndex]['answer]의 요소들은 Answer위젯에 buttonText속성으로 사용된다.

 

.toList()

- 이것이 없었다면 Answer위젯들이 모인 iterable객체가 map의 return값으로 나왔을 것이다.

- 그런데 toList()를 통해 리스트가 되었다.

 

... (spread operator)

=> question[_questionIndex]['answer] as List<String> 앞에 ...이 붙어 있다.

이것은 의미를 따로 갖고있는 것인데, 리스트안에 리스트가 들어갈 때, 이 operator을 써주면

안에 있는 리스트는 해체된다.

 

따라서, 리스트 안에 들어간 리스트들의 값들이 바깥의 리스트의 값이 된다.

 

여기코드에서 spread operator를 사용한 이유는 

사실은 저 코드가 위치한 곳이 column의 children의 위젯 리스트 안이기 때문이다.

children의 위젯 리스트 안에 list로 리턴이되었기에, 우리는 speard operator를 통해서

Answer위젯들이 column의 children 위젯 리스트의 값이 되도록 설정한 것이다.

 

 

 

위 코드를 사용한 이유는

question[_questionIndex]['answer] as List<String> 이 _questionIndex에 따라 리스트가 달라지며,

도출된 리스트들의 값이 항상 똑같지 않을 수 있기 때문이다.

우리는 따라서 위 코드를 통해, 도출된 리스트 수에 맞게 동적으로 Answer 위젯들을 만들어 낼 수 있었다.

 

 

 

 

반응형
Comments