Dart 3 함수형 프로그래밍
2022. 10. 3. 18:55ㆍ프로그래밍 언어/Flutter
List <-> Map , Set 변환
void main() {
List<String> blackPink = ['로제','지수','제니','리사','제니'];
print(blackPink); // [로제, 지수, 제니, 리사, 제니]
// List -> Map
print(blackPink.asMap()); // {0: 로제, 1: 지수, 2: 제니, 3: 리사, 4: 제니}
// List -> Set
print(blackPink.toSet()); // {로제, 지수, 제니, 리사}
// Map -> List
Map blackPinkMap =blackPink.asMap();
print(blackPinkMap.keys.toList()); // [0, 1, 2, 3, 4]
print(blackPinkMap.values.toList()); // [로제, 지수, 제니, 리사, 제니]
Set blackPinkSet =Set.from(blackPink);
// Set -> List
print(blackPinkSet.toList()); // [로제, 지수, 제니, 리사]
}
.map 키워드로 자료구조 변환 하기
Arrow 함수로 parsing 쉽게하기
void main() {
List<String> blackPink = ['로제','지수','제니','리사','제니'];
// .map 은 매번 새 list 를 만들어서 리턴한다.
final newblackPink = blackPink.map((x){
return '블랙핑크 $x';
});
print(blackPink);
print(newblackPink.toList());
// arrow 로 간소화 가능
final newblackPink2 = blackPink.map((x)=> '블랙핑크 $x');
print(newblackPink2.toList());
// 예시
String number ='12345';
List numberlist = number.split('');
final parsed =numberlist.map((x)=> '$x.jpg').toList();
print(parsed);
}
map 도 MapEntry로 수정가능!
void main() {
Map<String, String> marvel = {
'Iron Man': '아이언맨',
'Captain America': '캡팁아메리카',
'Hulk': '헐크',
};
final result = marvel.map(
(key, value) => MapEntry(
'Marvel $key',
'마블 $value',
),
);
print(result); //{Marvel Iron Man: 마블 아이언맨, Marvel Captain America: 마블 캡팁아메리카, Marvel Hulk: 마블 헐크}
// 값 수정 후 List로 변환
final keys = marvel.keys.map((x)=> 'Marvel $x').toList();
final values =marvel.values.map((x)=>'마블 $x').toList();
print(keys);// [Marvel Iron Man, Marvel Captain America, Marvel Hulk]
print(values); // [마블 아이언맨, 마블 캡팁아메리카, 마블 헐크]
}
Set도 변경가능!
void main() {
Set blackPinkSet ={
'로제',
'지수',
'제니',
'리사',
};
final newblackPinkSet = blackPinkSet.map((x)=>'블랙핑크 $x').toSet();
print(newblackPinkSet);
}
Where 로 리스트 값 필터링 가능
-> 새로운 iterable 을 반환한다.
void main() {
List<Map<String,String>> people =[
{
'name':'지수',
'group':'블랙핑크',
},
{
'name':'리사',
'group':'블랙핑크',
},
{
'name':'RM',
'group':'BTS',
},
{
'name':'뷔',
'group':'BTS',
},
];
print(people);// [{name: 지수, group: 블랙핑크}, {name: 리사, group: 블랙핑크}, {name: RM, group: BTS}, {name: 뷔, group: BTS}]
final blackPink = people.where((x)=> x['group']=='블랙핑크').toList();
final bts = people.where((x)=> x['group']=='BTS').toList();
print(blackPink); // [{name: 지수, group: 블랙핑크}, {name: 리사, group: 블랙핑크}]
print(bts); // [{name: RM, group: BTS}, {name: 뷔, group: BTS}]
}
reduce 는
첫 원소만 prev
두번쨰 원소 next
그 다음 루프부턴
return 값을 prev에
셋째 원소를 next에 넣는다. 그 이후로는
void main() {
List<int> numbers =[1,2,3,4,5];
final result = numbers.reduce((prev,next){
print('---------');
print('previous : $prev');
print('next : $next');
print('total : ${prev+next}');
return prev+ next;
});
print(result); // 15
}
아래와 같이 함축해서 쓸수있음.
void main() {
List<int> numbers =[1,2,3,4,5];
// reduce 는 실행하는 리스트의 멤버 타입과 리턴타입이 동일해야만 사용할 수 있다.
final result = numbers.reduce((prev,next)=> prev + next);
print(result); // 15
List<String> words =[
'안녕하세요.',
'저는',
'코드팩토리입니다.',
];
// 에러 뜸. : 멤버타입이 String인데, return 타입이 int 이기때문에 안됨.
final sentence = words.reduce((prev,next) =>prev.length + next.length);
print(sentence);
}
Fold 를 쓰면 멤버타입 != 리턴타입도 가능함.
reduce 와 다른점은
1) 리턴값을 모르기때문에 정의해줘야됨. ex) <int>
2) 첫 루프에
prev 값이 앞에 0 값이 들어가게되고, next에 첫번쨰 원소가 들어가게됨.
void main() {
List<int> numbers =[1,2,3,4,5];
final sum = numbers.fold<int> (0,(prev,next){
print('-----');
print('prev : $prev');
print('next : $next');
print('total : ${prev + next}');
return prev+ next;
});
print(sum);
}
next 에만 length 를 추가해주는게 포인트!
void main() {
List<int> numbers =[1,2,3,4,5];
final sum = numbers.fold<int> (0,(prev,next)=> prev+next);
List<String> words =[
'안녕',
'나는',
'코드팩토리야',
];
final sentence = words.fold<String>('',(prev,next)=> prev+next);
print(sentence);// 안녕나는코드팩토리야
final lenSum = words.fold<int>(0,(prev,next)=> prev+next.length);
print(lenSum); // 10
}
Cascading Operator
: 리스트 값들 풀어 넣기
... 사용시 새로운 리스트를 만든다.
void main() {
List<int> even =[
2,4,6,8
];
List<int> odd =[
1,3,5,7
];
// cascading operator
// ...
print([even,odd]); // [[2, 4, 6, 8], [1, 3, 5, 7]]
print([...even,...odd]); // [2, 4, 6, 8, 1, 3, 5, 7]
print(even ==[...even]); // false
}
실제 프로젝트에서는 오타방지 및 값 보장을 위해 class를 쓰는게 국룰임.
List - > class 로 변환
void main() {
List<Map<String,String>> people =[
{
'name':'지수',
'group':'블랙핑크',
},
{
'name':'리사',
'group':'블랙핑크',
},
{
'name':'RM',
'group':'BTS',
},
{
'name':'뷔',
'group':'BTS',
},
];
print(people);
final parsedPeople =people.map(
(x) => Person(
name : x['name']!, // map 안의 값을 확인할 수없기떄문에 null 이 아니라는 ! 를 추가해줘야 에러가 안남.
group : x['group']!,
),
);
final bts = parsedPeople.where((x) => x.group =='BTS');
print(parsedPeople); //// 바로 출력하면 [Instance of 'Person', Instance of 'Person', Instance of 'Person', Instance of 'Person']
// toString override 하면, [Person( name: 지수, group: 블랙핑크 ), Person( name: 리사, group: 블랙핑크 ), Person( name: RM, group: BTS ), Person( name: 뷔, group: BTS )]
print(bts); // (Person( name: RM, group: BTS ), Person( name: 뷔, group: BTS ))
}
class Person{
final String name;
final String group;
Person({
required this.name,
required this.group,
});
@override
toString(){
return 'Person( name: ${this.name}, group: ${this.group} )';
}
}
함수형 프로그래밍의
장점은 chaining 하면서 계속 새로운 값을 리턴할수있다.
단점은 너무 간소화된 코드라 타인과 협업시 불편할 수 있다.
'프로그래밍 언어 > Flutter' 카테고리의 다른 글
INSTALL_FAILED_INSUFFICIENT_STORAGE 해결법 (0) | 2022.10.10 |
---|---|
Dart 4 비동기 프로그래밍 (0) | 2022.10.03 |
Dart 2 객체지향 프로그래밍 (0) | 2022.10.02 |
Dart 언어 기본기 (0) | 2022.10.02 |
flutter 2강 (0) | 2022.10.02 |