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