인프런 무료 강의
https://www.inflearn.com/course/lecture?courseSlug=dart-%EC%96%B8%EC%96%B4-%EC%9E%85%EB%AC%B8&unitId=107600
DartPad
https://dartpad.dev/
// Functional Programming
// List []
// Map {} (key / value)
// Set {} 중복값 x
void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니', '리사'];
print(blackPink) // [로제, 지수, 리사, 제니, 리사]
print(blackPink.asMap()); // {0: 로제, 1: 지수, 2: 리사, 3: 제니, 4: 리사}
print(blackPink.toSet()); // {로제, 지수, 리사, 제니}
}
List
를 형변환 시켜줄 수 있다.asMap()
을 사용하면 Map
형태로 변형된다.toSet()
을 사용하면 Set
형태로 변형된다.void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니', '리사'];
Map blackPinkMap = blackPink.asMap();
print(blackPinkMap); // {0: 로제, 1: 지수, 2: 리사, 3: 제니, 4: 리사}
print(blackPinkMap.keys.toSet()); // {0, 1, 2, 3, 4}
print(blackPinkMap.values.toList()); // [로제, 지수, 리사, 제니, 리사]
Set blackPinkSet = Set.from(blackPink);
print(blackPinkSet); // {로제, 지수, 리사, 제니}
}
List
형태를 Map
에 asMap()
메서드를 사용하여 담아놓고 사용할 수도 있다.toList()
는 List
형태로 변형해준다.Set
은 중복값을 하나로 자동처리 해준다.void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니'];
final sayBlackPink = blackPink.map((el) {
return '블랙핑크 $el';
});
print(blackPink); // [로제, 지수, 리사, 제니]
print(sayBlackPink); // (블랙핑크 로제, 블랙핑크 지수, 블랙핑크 리사, 블랙핑크 제니)
print(sayBlackPink.toList()); // [블랙핑크 로제, 블랙핑크 지수, 블랙핑크 리사, 블랙핑크 제니]
// arrow function
final sayBlackPink2 = blackPink.map((el) => '블랙핑크 $el');
print(sayBlackPink2.toList());
// [블랙핑크 로제, 블랙핑크 지수, 블랙핑크 리사, 블랙핑크 제니]
}
print(sayBlackPink)
로 출력하면, Iterable
형태인 ()
로 나타난다.toList()
붙여주어 여러 List method
를 사용하기 위해 List
형태로 변형시킨다void main() {
String num = '12345';
final numList = num.split('');
final numListJpg = numList.map((el) => '$el.jpg').toList();
print(numListJpg); // [1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg]
}
void main() {
Map<String, String> myFamily = {
'Dad': 'John',
'Mom': 'Amy',
'Daughter' : 'Ellie',
'Son' : 'Paul',
};
final myFamilyRes = myFamily.map((key, value) => MapEntry(
'I am $key', 'My nams is $value'
));
print(myFamily);
// {Dad: John, Mom: Amy, Daughter: Ellie, Son: Paul}
print(myFamilyRes);
// {I am Dad: My nams is John, I am Mom: My nams is Amy, I am Daughter: My nams is Ellie, I am Son: My nams is Paul}
final keys = myFamily.keys.map((k) => '나는 $k').toList();
final values = myFamily.values.map((v) => '나는 $v').toList();
print(keys);
// [나는 Dad, 나는 Mom, 나는 Daughter, 나는 Son]
print(values);
// [나는 John, 나는 Amy, 나는 Ellie, 나는 Paul]
}
Map
형태도 map()
을 사용할 수 있다.parameter
로 Map
의 구성요소인 key
와 value
가 들어간다.iterable()
을 toList()
로 변경시킨다.void main() {
Set blackPinkSet = {
'제니', '로제', '리사', '지수'
};
final blackPinkSetRes = blackPinkSet.map((el) => '나는 $el').toSet();
print(blackPinkSetRes); // {나는 제니, 나는 로제, 나는 리사, 나는 지수}
}
Set
형태도 map()
를 사용할 수 있다.iterable()
로 반환하므로, toSet()
을 붙여 Set
형태로 변형시킨다.void main() {
// List 안에 Map 을 넣어준다. 제너릭으로 Type 표시!
List<Map<String, int>> market = [
{
'Strawberry': 1,
'price': 15000,
},
{
'Cola': 4,
'price': 2500,
},
{
'Ice-cream': 8,
'price': 6000,
},
{
'beef': 2,
'price': 45000,
}
];
// target 이 절대 null이 아님을 (non-nullable) 처리해주기 위해 느낌표(!)를 붙여줌
final marketPrice = market.where((el) => el['price']! >= 10000).toList();
print(marketPrice); // [{Strawberry: 1, price: 15000}, {beef: 2, price: 45000}]
}
where()
은 원본을 변경시키지 않고 새로운 것을 반환시킨다.true
인 것들만 filter
하여 반환시켜준다.void main() {
List<int> numLi = [1, 10, 3, 8, 2];
final numLiReduce = numLi.reduce((prev, next) {
print('prev : $prev'); // 처음에만 numLi의 첫 요소인 1
print('next : $next'); // 10
print('prev * next : $prev * $next ===> 다음 prev가 됨');
// 1 * 10 : 10 ===> 다음 prev가 됨
return prev * next;
});
print(numLiReduce); // 480
}
reduce()
는 파라미터로 prev
, next
를 넣어준다.prev
에는 return
해주는 값이 축적과 함께 할당이 된다 (처음에 실행시에만, reduce()
를 걸어준 List
의 첫요소가 들어감)next
는 계속해서 다음 요소가 들어간다reduce
를 실행하는 타겟의 type
과 똑같은 type
을 반환해주어야 한다.List
가 int
타입이라면 reduce
의 반환값도 오직 int type
이여야 한다. 아님 에러! void main() {
List<String> intro = ['나는', '졸리다', '오늘 빡센 하루', '잘자'];
final introPhrase = intro.reduce((prev, next) => prev + ' ' + next);
print(introPhrase); // 나는 졸리다 오늘 빡센 하루 잘자
}
void main() {
List<int> num = [10, 20, 30, 40];
// type 설정
// 0 으로 initial value 설정
final numSum = num.fold<int>(0, (prev, next) => prev + next);
print(numSum); // 100
List<String> str = ['나는', '수박이', '먹고싶어요!'];
final strPhrase = str.fold<String>('', (prev, next) => prev + next);
print(strPhrase); // 나는수박이먹고싶어요!
final strLength = str.fold<int>(0, (prev, next) => prev + next.length);
print(strLength); // 11
}
reduce()
와 거의 비슷한데 다르다.fold
를 실행하는 타겟의 type
따라가지 않아도 된다.type
을 알아서 설정하여 반환이 가능하다.initial
값, 초기값이다. (처음에 초기값이 prev
에 할당됨)js
로 치면 spread operator
와 동일하다void main() {
List<int> num = [1,2,3,4];
List<int> num2 = [5,6,7,8];
print([...num, ...num2]); [1, 2, 3, 4, 5, 6, 7, 8]
}
json
형태로 데이터를 받으면, class
형으로 변환해서 사용해야 더 편리하다.List
나 Map
, Set
형태로 그대로 사용하면, 내부의 데이터를 명확하게 알 수 없기 때문이다.chaining
할 수 있다.// class 로 설계도를 만들어준다.
class Market {
final String name;
final String price;
// named parameter
Market({
required this.name,
required this.price,
});
String toString() {
return 'Market(name: $name, price: $price)';
}
}
void main() {
List<Map<String, String>> market = [
{
'name': 'Strawberry',
'price': '15000',
},
{
'name': 'Cola',
'price': '2500',
},
{
'name': 'Ice-cream',
'price': '6000',
},
{
'name': 'Beef',
'price': '45000',
}
];
print(market);
// [{name: Strawberry, price: 15000}, {name: Cola, price: 2500}, {name: Ice-cream, price: 6000}, {name: Beef, price: 45000}]
// List 에 값이 있는지 없는지 명확히 알 수 없기에 느낌표(!)를 붙여 값이 있음을 증명
final marketMap = market
.map((el) => Market(name: el['name']!, price: el['price']!))
.toList();
print(marketMap);
// [Market(name: Strawberry, price: 15000), Market(name: Cola, price: 2500), Market(name: Ice-cream, price: 6000), Market(name: Beef, price: 45000)]
json
형태로 받은 데이터를 class
를 통해, 사용하기 좋게 바꿔주었다.// 이런식으로 함수 chaining 도 할 수 있다.
final marketMap = market.map((el) =>
Market(name: el['name']!, price: el['price']!)).toList()
.where((el) => el.price == '15000')
.fold<String>('', (prev, next) => prev + next.name);
print(marketMap); // Strawberry