728x90
직전 포스팅에서 dart OOP 개념에 대해서 알아보았는데요, 이번에는 dart functional programming 개념에 대해서 알아보겠습니다.
필자는 깊진 않지만 여러 프로그래밍 언어에 대한 경험(컴공)이 있기 때문에 순전히 필자의 기준으로 작성했으니 이 포스트는 프로그래밍 언어를 처음 배우시는 분에겐 맞지 않을 수 있으니 유의!!!
다른 언어를 배워본 경험이 있으신 분들은 가볍게 보시면 dart 문법 금방 아실 거라고 생각합니다.
**음슴체**
형 변환(list, map, set)
void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니', '제니'];
print(blackPink); // => []
print(blackPink.asMap()); // List -> Map {}
print(blackPink.toSet()); // List -> Set ()
Map blackPinkMap = blackPink.asMap();
print(blackPinkMap.keys.toList()); // Map keys -> list
print(blackPinkMap.values.toList()); // Map values -> list
print(blackPinkMap.keys.toSet()); // Map keys -> set
print(blackPinkMap.values.toSet()); // Map keys -> set
Set blackPinkSet = Set.from(blackPink); // list -> set
print(blackPinkSet.toList()); // set -> list
}
list 매핑
void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니'];
// map을 쓰면 새로운 iterable이 나온다.
// iterable은 잘 사용하지 않아서 list로 변환해서 자주 사용한다.
final newBlackPink = blackPink.map((x){
return '블랙핑크 $x';
});
print(blackPink);
print(newBlackPink.toList());
// arrow function 사용 - 간결
final newBlackPink2 = blackPink.map((x) => '블랙핑크 $x');
print(newBlackPink2.toList());
print(blackPink == blackPink); // => true
print(newBlackPink == blackPink); // => false
print(newBlackPink == newBlackPink2); // => false
// goal : [1.jpg, 3.jpg, 5.jpg, 7.jpg, 9.jpg]
String number = '13579';
final parsed = number.split('').map((x) => '$x.jpg').toList();
print(parsed);
}
map 매핑
void main() {
Map<String, String> harryPotter = {
'harry Potter': '해리 포터',
'Ron Weasley': '론 위즐리',
'Hermione Granger': '헤르미온느 그레인저',
};
// map 자체를 새로운 map으로 만드는 방법
final result = harryPotter.map(
(key, value) => MapEntry(
'Harry Potter Character $key',
'해리포터 캐릭터 $value',
),
);
print(harryPotter);
print(result);
// key, values 값 각각을 맵으로 만드는 방법(리스트로 변환 많이 함)
final keys = harryPotter.keys.map((x) => 'HPC $x').toList();
final values = harryPotter.values.map((x) => '해리포터 $x').toList();
print(keys);
print(values);
}
set 매핑
리스트와 매우 유사함.
void main() {
Set blackPinkSet = {
'로제',
'지수',
'제니',
'리사',
};
final newSet = blackPinkSet.map((x) => '블랙핑크 $x').toSet();
print(newSet);
}
where
void main() {
List<Map<String, String>> people = [
{
'name' : '로제',
'group' : '블랙핑크',
},
{
'name' : '지수',
'group' : '블랙핑크',
},
{
'name' : 'RM',
'group' : 'BTS',
},
{
'name' : '뷔',
'group' : 'BTS',
},
];
print(people);
final blackPink = people.where((x) => x['group'] == '블랙핑크');
final bts = people.where((x) => x['group'] == 'BTS');
print(blackPink);
print(bts);
}
reduce
아래 예제를 보면 numbers는 int이기 때문에 result도 int여야 하는 것이다.
void main() {
List<int> numbers = [
1,
3,
5,
7,
9,
];
final result = numbers.reduce((prev, next){
print('--------------');
print('previous $prev');
print('next $next');
print('total : ${prev+next}');
return prev+next;
});
print(result);
List<String> words = [
'안녕하세요 ',
'저는 ',
'김아무개입니다.',
];
final sentence = words.reduce((prev, next) => prev + next);
print(sentence);
// 오류 발생 : words는 string인데 length는 int이다. 즉, reduce는 해당 리스트와 같은 타입을 반환해줘야 한다.
words.reduce((prev, next) => prev.length + next.length); // x
}
fold
fold를 사용해 반환 값의 type을 변경할 수 있다.
void main() {
List<int> numbers = [1, 3, 5, 7, 9];
// fold : 첫 시작 값 명시
final sum = numbers.fold<int>(0, (prev, next) => prev + next);
print(sum);
List<String> words = [
'안녕하세요 ',
'저는 ',
'김아무개입니다.',
];
final sentence = words.fold('', (prev, next) => prev + next);
print(sentence);
// fold를 사용해 반환값의 type을 변경할 수 있다.
final count = words.fold<int>(0, (prev, next) => prev + next.length); // o
print(count);
}
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 == [...even]); // => false
}
실제 예시 - class와 functional
void main() {
final 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']!, // name과 group의 값들이 존재한다는 것을 명시하기 위해 ! 붙임
group: x['group']!,
),
)
.toList();
// 결과가 Instance of class명 리스트로 나오는데, 이 기본값을 변경하기 위해서 toString의 override
print(parsedPeople);
// for (Person person in parsedPeople) {
// print(person.name);
// print(person.group);
// }
final bts = parsedPeople.where((x) => x.group == 'BTS');
print(bts);
// 와 과정을 한번에 처리 가능
final result = people
.map(
(x) => Person(
name: x['name']!,
group: x['group']!,
),
)
.where((x) => x.group == 'BTS')
.fold(0, (prev, next) => prev + next.name.length);
print(result);
}
class Person {
final String name;
final String group;
Person({
required this.name,
required this.group,
});
// 기본값 변경
@override
String toString() {
return 'Person(name:$name, group:$group)';
}
}
이번 포스팅은 dart functional programming에 대해 알아보았습니다.
다음 포스팅은 asynchronous programming에 대해 알아보겠습니다. 감사합니다.
'flutter > dart' 카테고리의 다른 글
flutter를 위한 dart 기본 문법 (4) - async programming (0) | 2022.12.01 |
---|---|
flutter를 위한 dart 기본 문법 (2) - OOP (0) | 2022.11.30 |
flutter를 위한 dart 기본 문법 (1) (0) | 2022.11.30 |
댓글