Flutter 캠프 8일차

은성·2025년 12월 3일

Flutter 본캠프

목록 보기
8/57
post-thumbnail

오늘의 내용

Git기초, 문제풀이, 함수형 프로그래밍 과 Dart , 과제 시작

Git 기초

https://github.com/eunseong0207/flutter-study-9

  • Readme 참고

VSCord단축키

command + Shift + N > : VSCord 새로 키는 단축키
command + O > : VSCord 폴더 여는 단축키
command + J : VSCord 내에서 터미널 열기

문제풀이

  • 각 강의 마다 마지막 실습이라는 내용으로 문제가 제공이된다.
    해당 문제들은 나한테 너무 어려웠다.
    그래서 내가 어제 배운내용을 AI에게 설명한 후,
    문제들을 제출해달라고 하고 풀어봤다.

함수형 프로그래밍

  • 함수의 연속으로 프로그램을 구성하는 방식
    더 안정적이고 간결한 코드를 작성하기 위함

메서드 체이닝

  • .을 사용해서 여러개의 함수를 하나로 연결하는 방식
int number = -12345
var result = number.abs().toString().contains('3'); // .누르면 넣을수 있는 메서드 목록을 보여줌
print(result); // true

abs() 는 절댓값을 반환하는 함수,
toString() 은 문자형으로 바꿔주는 함수 랍니다 

String word = 'abcd';
var index = word.toUpperCase().indexOf('B');
print(index); // 1

toUpperCase() 는 문자열의 모든 문자를 대문자로 바꾸는 함수 랍니다  🙂

순수 함수

  • 같은 입력값에 대해서 항상 같은 출력값이 나오는 함수
  • 가변적인 데이터의 사용을 최소하 하여 프로그램을 구성하는 방식
    출력값이 항상 그 함수의 매개변수 (입력값)에만 의조하게 한다는 뜻.
int add(int a, int b) {
  return a + b;
}

void main() {
  int result = add(3, 4);
  print(result); // 7
}

add() 의 코드 블록을 보면 함수의 결과값이 함수의 매개변수에만 의존하고 있죠 ?
함수 밖에 있는 변수를 함수 안에서 사용하지 않는군요 !

int add(int a, int b) {
  return a + b;
}

a 에 1, b 에 2 를 넣으면 항상 3 이 나오겠죠 ?

int multiply(int a, int b) {
  return a * b;
}

a 에 3, b 에 4 를 넣으면 항상 12 가 나오겠죠 ?

int getTotal(List<int> numbers) {
  int result = 0;
  for (var number in numbers) {
    result += number;
  }
  return result;
}

numbers 에 [1, 2, 3, 4, 5] 를 넣으면 항상 15 가 나오겠죠 ?

  • 같은 값을 입력하면 항상 같은 값이 나오기 때문에 예상치 못 한 상황(부작용)이 생길일이 줄어듬

부작용

int number = 0;

void increaseNumber() {
  number += 1;
}

void main() {
  print(number); // 0
  increaseNumber();
  print(number); // 1
}

increaseNumber() 안에서 함수 외부의 값을 변경하고 있네요 ?
이렇게 하면 예상하지 못 했던 상황이 발생할 수 있어서 위험해요 🚨
의도한 것이라면 상관없지만,
number 를 변경하려고 했던 것이 아니라면 .. 대참사잖아요 !!
  • 참고로, 이런 구성 방식을 명령형 프로그래밍 방식 이라고 해요 !

자주 사용하는 함수

형변환 함수

  • 특정 타입의 데이터를 다른 타입의 데이터로 변환하는 함수

torString()

-값을 String 타입으로 변환한 값을 반환한다.

int number = 42;
var result = number.toString();
print(result); // 42
print(result.runtimeType); // String

runtimeType 은 어떤 타입인지 반환해 주는 친구랍니다 🙂

double number = 1.5;
var result = number.toString();
print(result); // 1.5
print(result.runtimeType); // String

double 타입도 가능 !!

int.parse("")

  • String타입의 값을int타입으로 변환한 값을 반환한다.
    int타입으로 바꿔줄 문자열의 매개변수에 전달한다.
    • 변환이 어려운 경우에는 오류가 발생함
String number = '123';
var result = int.parse(number);
print(result); // 123
print(result.runtimeType); // int

오류가 나지 않은 정상 코드

tring invalidNumber = 'abcd';
var result = int.parse(invalidNumber);
print(result);

‘abcd’ 는 숫자로 변환이 안 되겠죠 ? 그래서 오류가 난답니다 🚨
참고로, <FormatException> 이라는 오류가 발생하는데
이 친구는 7강에서 다룰 예정이니까 궁금해도 조금만 참아요 !

int.tryParse("")

  • 형변환 실패시 오류나지 않는 함수
  • String타입의 값을int타입으로 변환한 값을 반환한다.
    int타입으로 바꿔줄 문자열의 매개변수에 전달한다.
    • 변환이 어려운 경우에는 오류대신 null을 반환한다.
String number = '123';
var result = int.tryParse(number);
print(result); // 123
print(result.runtimeType); // int

형변환에 성공하면 int.parse() 와 같이 동작해요.

String invalidNumber = 'abcd';
var result = int.tryParse(invalidNumber);
print(result); // null

‘abcd’ 를 int 타입으로 변환할 수 없기 때문에
null 을 반환해요.

double.parse("")

  • String타입의 값을 double타입으로 변환한 값을 반환한다.
    double타입으로 바꿔줄 문자열을 매개변수에 전달한다.
    • 변환이 어려운 경우에는 오류가 발생한다.
String number = '123.4';
var result = double.parse(number);
print(result); // 123.4
print(result.runtimeType); // double


String invalidNumber = 'abcd';
var result = double.parse(invalidNumber);
print(result);

‘abcd’ 는 숫자로 변환이 안 되겠죠 ?
이 경우에도 FormatException 이 발생해요.

double.tryParse("")

  • 형변환 실패시 오류나지 않는 함수
  • String타입의 값을double타입으로 변환한 값을 반환한다.
    double타입으로 바꿔줄 문자열의 매개변수에 전달한다.
    • 변환이 어려운 경우에는 오류대신 null을 반환한다.
String number = '123.4';
var result = double.tryParse(number);
print(result); // 123.4
print(result.runtimeType); // double

형변환에 성공하면 double.parse() 와 같이 동작해요.

String invalidNumber = 'abcd';
var result = double.tryParse(invalidNumber);
print(result); // null

‘abcd’ 를 double 타입으로 변환할 수 없기 때문에
null 을 반환해요.

toList()

  • 특정 collection 타입의 값을List타입으로 변환한 값을 반환해요.
Set<String> fruitSet = {'사과', '오렌지', '수박'};
var fruitList = fruitSet.toList();
print(fruitList); // [사과, 오렌지, 수박]
print(fruitList.runtimeType); // List<String>

타입 추론이 적용된 것도 확인할 수 있네요 !

Map<String, String> people = {'Alice': 'Student', 'Bob': 'Teacher'};
var peopleList = people.toList();
print(peopleList);
// Error: The method 'toList' isn't defined for the class 'Map<String, String>'.

참고로, 모든 Collection 타입에 사용할 수 있지는 않아요 🤣
Map 에는 적용하지 못 한답니다

toset()

  • 특정collection타입의 값을 Set타입으로 변환한 값을 반환한다.
    Set 은 중복값을 허용하지 않기 때문에 Collection
    값에 중복값이 있으면 중복값을 제외한 Set 을 반환해요.
List<String> fruitList = ['사과', '오렌지', '수박'];
var fruitSet = fruitList.toSet();
print(fruitSet); // {사과, 오렌지, 수박}
print(fruitSet.runtimeType); // Set<String>

타입 추론이 적용된 것도 확인할 수 있네요 !

Map<String, String> people = {'Alice': 'Student', 'Bob': 'Teacher'};
var peopleSet = people.toSet();
print(peopleSet);
// Error: The method 'toSet' isn't defined for the class 'Map<String, String>'.

마찬가지로, 모든 Collection 타입에 사용할 수 있지는 않아요 🤣
Map 에는 적용하지 못 한답니다 ㅜㅜ

List<String> fruitList = ['사과', '오렌지', '수박', '사과'];
var fruitSet = fruitList.toSet();
print(fruitSet); // {사과, 오렌지, 수박}

fruitList 에 ‘사과’ 가 중복되어 있기 때문에
fruitSet 에는 ‘사과’ 가 1개만 들어간 것을 볼 수 있어요.

asMap()

  • 특정 collection 타입의 값을 Map 타입으로 변환한 값을 반환한다.
List<String> fruitList = ['사과', '오렌지', '수박'];
var fruitMap = fruitList.asMap();
print(fruitMap); // {0: 사과, 1: 오렌지, 2: 수박}

List 의 Index 가 Map 의 키로, List 의 값이 Map 의 값으로 할당돼요.
Map 의 키는 고유하다고 했죠 ? List 의 Index 도 고유하니까 안성맞춤 👍🏼

List<String> fruitList = ['사과', '오렌지', '수박', '사과'];
var fruitMap = fruitList.asMap();
print(fruitMap); // {0: 사과, 1: 오렌지, 2: 수박, 3: 사과}

Map 의 값은 중복되어도 된다고 했죠 ? 그래서 중복값이 적용되었나 보군요 !

Set<String> fruitSet = {'사과', '오렌지', '수박'};
var fruitMap = fruitSet.asMap();
print(fruitMap);
// Error: The method 'asMap' isn't defined for the class 'Set<String>'.

마찬가지로, 모든 Collection 타입에 사용할 수 있지는 않아요 🤣
Set 은 Index 가 없기 때문에 Set 에는 적용하지 못 한답니다 ㅜㅜ

Set을 Map으로 변환할 수 있는 방법

Set<String> fruitSet = {'사과', '오렌지', '수박'};
var fruitList = fruitSet.toList();
var fruitMap = fruitList.asMap();
print(fruitMap); // {0: 사과, 1: 오렌지, 2: 수박}


고차 함수

  • 함수를 다루는 함수
    Collection 타입의 데이터에 있는 요소를 처리하거나 변환할 때 사용해요.

Map()

Collection 타입인 데이터의 각 요소에 특정 함수를 적용한
새로운 Collection 타입의 데이터를 반환해요.

Map(([매개변수]) { return [매개변수에 적용할 동작] });

List<String> fruitList = ['사과', '오렌지', '수박'];
var delicious = fruitList.map((fruit) {
  var word = '맛있는 ';
  word += fruit;
  return word;
});
print(delicious); // (맛있는 사과, 맛있는 오렌지, 맛있는 수박)

fruitList 의 각 요소에 ‘맛있는 ‘ 이 추가되었네요 !

List<String> fruitList = ['사과', '오렌지', '수박'];
var delicious = fruitList.map((fruit) {
	return '맛있는 $fruit';
});
print(delicious); // (맛있는 사과, 맛있는 오렌지, 맛있는 수박)

위에 있는 코드를 이렇게 줄일 수도 있어요 🤭

List<int> numbers = [1, 2, 3, 4, 5];
var doubledNumbers = numbers.map((n) {
	return n * 2;
});
print(doubledNumbers<); // (2, 4, 6, 8, 10)

numbers 의 각 요소에 2 를 곱한 값들이 반환되는군요 !

Set<String> carSet = {'BMW', '현대', '기아'};
var goodCar = carSet.map((car) {
	return '짱 멋진 $car';
});
print(goodCar); // (짱 멋진 BMW, 짱 멋진 현대, 짱 멋진 기아)

Set 에도 적용 가능 !!

Map<String, int> fruits = {'사과': 5, '포도': 2, '귤': 3};

var delicious = fruits.keys.map((fruit) {
	return '맛있는 $fruit';
});
print(delicious); // (맛있는 사과, 맛있는 포도, 맛있는 귤)

var numbers = fruits.values.map((number) {
	return '$number개';
});
print(numbers); // (5개, 2개, 3개)


Map(([매개변수]) => [매개변수에 적용할 동작] );

  • 매개변수에 적용할 동작을 한줄로 표현 가능한 경우에만 사용할 수 있다.
List<int> numbers = [1, 2, 3, 4, 5];
var doubledNumbers = numbers.map((n) => n * 2);
print(doubledNumbers); // (2, 4, 6, 8, 10)


List<String> fruits = ['사과', '오렌지', '수박'];
var delicious = fruits.map((fruit) => '맛있는 $fruit');
print(delicious); // (맛있는 사과, 맛있는 오렌지, 맛있는 수박)


특징

  • 원본 데이터를 직접 가공하지 않고 특정함수를 적용한 새로운 데이터를 반환한다.
List<String> alphabets = ['A', 'B', 'C', 'D'];
var lowercasedAlphabets = alphabets.map((alphabet) {
	return alphabet.toLowerCase()
});
print(lowercasedAlphabets); // (a, b, c, d)
print(alphabets); // [A, B, C, D]

alphabets 를 가지고 연산했지만, alphabets 는 그대로 !!

  • 원본 데이터와 크기가 같은 데이터를 반환한다.
List<String> alphabets = ['a', 'b', 'c', 'd'];
final uppercasedAlphabets = alphabets.map((alphabet) {
	return alphabet.toUpperCase()
});
print(alphabets); // [A, B, C, D]
print(alphabets.length); // 4
print(uppercasedAlphabets); // (A, B, C, D)
print(uppercasedAlphabets.length); // 4


where

  • Collection 타입의 데이터에 있는 각 요소들을 특정 조건에 넣었을 때
    참인 요소들만 필터링한 새로운 Collection 타입의 데이터를 반환한다.

where(([매개변수]) { return [조건식] });

  • colletion타입의 데이터에 있는 각 요소들을 특정 조건에 넣었을 때
    참인 요소들만 필터링한 새로운 Collection 타입의 데이터를 반환한다.
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.where((number) {
	return number > 5;
});
print(result); // (6, 7, 8, 9, 10)


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.where((fruit) {
	return fruit.length == 2;
});
print(result); // (사과, 수박)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.where((number) {
	return number.isEven
});
print(result); // (2, 4, 6)

참고로, isEven 은 짝수면 true, 홀수면 false 를 반환해요.
number.isEven 은 number % 2 == 0 와 같다고 보면 돼요 🙂

where(([매개변수]) => [조건식] );

  • 매개변수에 적용할 동작을 한줄로 표현 가능한 경우에만 사용 가능
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.where((n) => n > 5);
print(result); // (6, 7, 8, 9, 10)


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.where((f) => f.length == 2);
print(result); // (사과, 수박)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.where((n) => n.isEven);
print(result); // (2, 4, 6)


특징

  • 원본데이터를 직접 가공하지 않고, 특정 함수를 적용한 새로운 데이터를 반환한다.
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.where((number) {
	return number > 5
});
print(result); // (6, 7, 8, 9, 10)
print(numbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

numbers 를 가지고 연산했지만, numbers 는 그대로 !!

List<String> fruits = ['사과', '오렌지', '수박'];
var filteredFruits = fruits.where((fruit) {
	return fruit.length == 2
});
print(filteredFruits); // (사과, 수박)
print(fruits); // ['사과', '오렌지', '수박']

fruits 를 가지고 연산했지만, fruits 는 그대로 !!

  • 조건식이 참인 요소가 없는경우에는 빈값을 반환한다.
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.where((number) {
  return number > 10;
});
print(result); // ()


firstWhere()

  • Collection 타입의 데이터에 있는 각 요소들을 특정 조건에 넣었을 때
    참인 요소들 중 첫번째 요소를 반환한다.

firstWhere(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.firstWhere((number) {
	return number > 5;
});
print(result); // 6


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.firstWhere((fruit) {
	return fruit.length == 2;
});
print(result); // 사과


firstWhere(([매개변수]) => [조건식] );

  • 매개변수에 적용할 동작을 한줄로 표현 가능한 경우에만 사용
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.firstWhere((n) => n > 5);
print(result); // 6


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.firstWhere((f) => f.length == 2);
print(result); // 사과


특징

  • 원본 데이터를 직접 가공하지 않고, 특정 함수를 적용한 새로운 데이터를 반환한다.
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.firstWhere((number) => number > 2);
print(result); // 3
print(numbers); // [1, 2, 3, 4, 5]


  • 조건식이 참인 요소가 없는경우에는 오류가 발생한다.
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.firstWhere((number) {
  return number > 10;
});
print(result); // StateError


lastWhere()

  • Collection 타입의 데이터에 있는 각 요소들을 특정 조건에 넣었을 때
    참인 요소들 중 마지막 요소를 반환해요.

lastWhere(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.lastWhere((number) {
	return number > 5;
});
print(result); // 10


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.lastWhere((fruit) {
	return fruit.length == 2;
});
print(result); // 수박


lastWhere(([매개변수]) => [조건식] );

  • 매개변수에 적용할 동작을 한줄로 표한 가능한경우에만 사용 가능
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.firstWhere((n) => n > 5);
print(result); // 6


List<String> fruits = ['사과', '오렌지', '수박'];
var result = fruits.firstWhere((f) => f.length == 2);
print(result); // 사과


특징

  • 원본 데이터를 직접 가공하지 않고 , 특정 함수를 적용한 새로운 데이터를 반환한다.
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.lastWhere((number) => number > 2);
print(result); // 5
print(numbers); // [1, 2, 3, 4, 5]


  • 조건식이 참인 요소가 없는경우에는 오류가 발생한다.
List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers.lastWhere((number) {
  return number > 10;
});
print(result); // StateError


reduce()

  • Collection 타입의 데이터에 있는 요소들을 하나의 값으로 결합해요.

reduce(([매개변수1], [매개변수2]) { return [적용할 동작] });

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.reduce((a, b) {
	return a + b;
});


List<int> numbers = [1, 2, 3, 4];
var result = numbers.reduce((a, b) {
  return a * b;
});


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
var result = words.reduce((a, b) {
  return a + b;
});


reduce(([매개변수1], [매개변수2]) => [적용할 동작] );

  • 매개변수에 적용할 동작을 한줄로 표현 가능한 경우에만 사용 가능
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.reduce((a, b) => a + b);


List<int> numbers = [1, 2, 3, 4];
var result = numbers.reduce((a, b) => a * b);


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
var result = words.reduce((a, b) => a + b);


  • 매개변수1 에는 이전 실행에서 반환된 값
    (첫번째 실행에서는 이전 실행이 없기 때문에 Collection 타입의 데이터에 있는 첫번째 값) 이 할당되고,
    매개변수2 에는 Collection 타입의 데이터에 있는 다음 값이 할당돼요.
List<int> numbers = [1, 2, 3, 4, 5];
int result = numbers.reduce((a, b) {
  print('a : $a');
  print('b : $b');
  print('a + b : ${a + b}');
  print('----------------------');
  return a + b;
});
print('result : $result');

/*
a : 1
b : 2
a + b : 3
----------------------
a : 3
b : 3
a + b : 6
----------------------
a : 6
b : 4
a + b : 10
----------------------
a : 10
b : 5
a + b : 15
----------------------
result : 15
*/


List<int> numbers = [1, 2, 3, 4];
int result = numbers.reduce((a, b) {
  print('a : $a');
  print('b : $b');
  print('a * b : ${a * b}');
  print('----------------------');
  return a * b;
});
print('result : $result');

/*
a : 1
b : 2
a * b : 2
----------------------
a : 2
b : 3
a * b : 6
----------------------
a : 6
b : 4
a * b : 24
----------------------
result : 24
*/


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
int result = words.reduce((a, b) {
  print('a : $a');
  print('b : $b');
  print('a + b : ${a + b}');
  print('----------------------');
  return a + b;
});
print('result : $result');

/*
a : 다트는 
b : 참 
a + b : 다트는 참 
----------------------
a : 다트는 참 
b : 재미있군 ?
a + b : 다트는 참 재미있군 ?
----------------------
result : 다트는 참 재미있군 ?
*/


특징

  • Collection 타입의 데이터와 같은 타입으로만 반환한다.
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.reduce((a, b) => '$a' + '$b');
// Error: A value of type 'String' can't be returned from a function with return type 'int'.

처음 실행될 때 초기값이 정수형인 1 이기 때문에
정수형과 문자형을 더할 수 없겠죠 ?

  • Collection 타입의 데이터에 요소가 없는 경우에는 오류가 발생해요 🚨
List<int> list = [];
var result = list.reduce((a, b) => a + b); // StateError


fold()

  • Collection 타입의 데이터에 있는 요소들을 하나의 값으로 결합해요.

fold(초기값, ([매개변수1], [매개변수2]) { return [적용할 동작] });

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.fold(0, (a, b) {
	return a + b
});


List<int> numbers = [1, 2, 3, 4];
var result = numbers.fold(1, (a, b) {
  return a * b;
});


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
var result = words.fold('앗, ', (a, b) {
  return a + b;
});


fold(초기값, ([매개변수1], [매개변수2]) => [적용할 동작] );

  • 매개변수에 적용할 동작을 한줄로 표현 가능한 경우에만 사용 가능
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.fold(0, (a, b) => a + b);


List<int> numbers = [1, 2, 3, 4];
var result = numbers.fold(1, (a, b) => a * b);


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
var result = words.fold('앗, ', (a, b) => a + b);


  • 매개변수1 에는 이전 실행에서 반환된 값 (첫번째 실행에서는 초기값) 이 할당되고,
    매개변수2 에는 Collection 타입의 데이터에 있는 다음 값이 할당돼요.
List<int> numbers = [1, 2, 3, 4, 5];
int result = numbers.fold(0, (a, b) {
  print('a : $a');
  print('b : $b');
  print('a + b : ${a + b}');
  print('----------------------');
  return a + b;
});
print('result : $result');

/*
a : 0
b : 1
a + b : 1
----------------------
a : 1
b : 2
a + b : 3
----------------------
a : 3
b : 3
a + b : 6
----------------------
a : 6
b : 4
a + b : 10
----------------------
a : 10
b : 5
a + b : 15
----------------------
result : 15
*/


List<int> numbers = [1, 2, 3, 4];
int result = numbers.fold(1, (a, b) {
  print('a : $a');
  print('b : $b');
  print('a * b : ${a * b}');
  print('----------------------');
  return a * b;
});
print('result : $result');

/*
a : 1
b : 1
a * b : 1
----------------------
a : 1
b : 2
a * b : 2
----------------------
a : 2
b : 3
a * b : 6
----------------------
a : 6
b : 4
a * b : 24
----------------------
result : 24
*/


List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
int result = words.fold('앗, ', (a, b) {
  print('a : $a');
  print('b : $b');
  print('a + b : ${a + b}');
  print('----------------------');
  return a + b;
});
print('result : $result');

/*
a : 앗, 
b : 다트는 
a + b : 앗, 다트는 
----------------------
a : 앗, 다트는 
b : 참 
a + b : 앗, 다트는 참 
----------------------
a : 앗, 다트는 참 
b : 재미있군 ?
a + b : 앗, 다트는 참 재미있군 ?
----------------------
result : 앗, 다트는 참 재미있군 ?
*/


특징

  • Collection 타입의 데이터와 다른 타입으로도 반환이 가능해요.
List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.fold('', (a, b) => '$a' + '$b');
print(result); // 12345
print(result.runtimeType); // String

초기값과 반환값만 잘 맞춰주면 다른 타입도 완전 가능 👍🏼

List<String> words = ['다트는 ', '참 ', '재미있군 ?'];
int result = words.fold(0, (a, b) {
  print('a : $a');
  print('b : $b');
  print('b length : ${b.length}');
  print('---------------');
  return a + b.length;
});
print('총 글자 수 : $result');

/*
a : 0
b : 다트는 
b length : 4
---------------
a : 4
b : 참 
b length : 2
---------------
a : 6
b : 재미있군 ?
b length : 6
---------------
총 글자 수 : 12
*/

length 는 요소의 개수를 반환한다고 했던 것 기억하시죠 ~?

  • Collection 타입의 데이터에 요소가 없어도 오류가 발생하지 않아요.
List<int> list = [];
var result = list.fold(0, (a, b) => a + b);
print(result); // 0

초기값이 있기 때문에 빈 Collection 이어도 오류가 발생하지 않아요 !

reduce() 랑 fold() 의 차이점

---reduce()Fold
초기값Collection 데이터의 첫번째 요소첫번째 매개변수에 넣어준 값
빈 Collection 사용 가능 여부XO
타입 유연성 여부 (Collection 의 요소 타입과반환 타입이 달라도 되는지)XO

any()

  • Collection 타입의 데이터에 있는 요소 중
    하나라도 주어진 조건을 만족하면 true 를 반환해요.

any(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.any((number) {
	return number.isEven;
});
print(result); // true

isEven 은 짝수일 때 true, 홀수일 때 false 를 반환해요.

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.any((number) {
 return number > 10;
 });
print(result); // false


any(([매개변수]) => [조건식] );

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.any((n) => n.isEven);
print(result); // true


List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.any((number) => number > 10);
print(result); // false


every()

  • Collection 타입의 데이터에 있는 모든 요소가
    주어진 조건을 만족하면 true 를 반환해요.

every(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.every((number) {
 return number > 0;
});
print(result); // true


List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.every((number) {
	return number.isEven;
});
print(result); // false


every(([매개변수]) => [조건식] );

List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.any((number) => number > 0);
print(result); // true


List<int> numbers = [1, 2, 3, 4, 5];
var result = numbers.every((n) => n.isEven);
print(result); // false


takeWhile()

  • Collection 타입의 데이터에 있는 요소들을 주어진 조건에 넣었을 때
    참이 되는 동안은 해당 요소들을 반환하고,
    조건이 처음으로 거짓이 되는 순간부터의 요소들은 모두 무시해요.

takeWhile(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.takeWhile((number) {
 return number < 4;
});
print(result); // (1, 2, 3)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.takeWhile((number) {
 return number.isOdd;
});
print(result); // (1)


takeWhile(([매개변수]) => [조건식] );

List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.takeWhile((number) => number < 4);
print(result); // (1, 2, 3)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.takeWhile((number) => number.isOdd);
print(result); // (1)


skipWhile()

Collection 타입의 데이터에 있는 요소들을 주어진 조건에 넣었을 때
참이 되는 동안은 해당 요소들을 건너뛰고,
조건이 처음으로 거짓이 되는 순간부터의 요소들을 모두 반환해요.

skipWhile(([매개변수]) { return [조건식] });

List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.skipWhile((number) {
 return number < 4;
});
print(result); // (4, 5, 6)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.skipWhile((number) {
 return number.isOdd;
});
print(result); // (2, 3, 4, 5, 6)


skipWhile(([매개변수]) => [조건식] );

List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.skipWhile((number) => number < 4);
print(result); // (4, 5, 6)


List<int> numbers = [1, 2, 3, 4, 5, 6];
var result = numbers.skipWhile((number) => number.isOdd);
print(result); // (2, 3, 4, 5, 6)


Map() + Where()

List에 있는 숫자들 각각에 2를 곱한 후 5보다 큰 값들을 반환하고 싶다면?

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var doubledNumbers = numbers.map((number) => number * 2);
var result = doubledNumbers.where((number) => number > 5);
print(result); // (6, 8, 10, 12, 14, 16, 18, 20)


List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers
  .map((number) => number * 2)
  .where((number) => number > 5);
print(result); // (6, 8, 10, 12, 14, 16, 18, 20)


List 에 있는 숫자들 중 짝수들만 골라낸 후 각각을 제곱한 값들의 합을 반환하고 싶다면 ?

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var evenNumbers = numbers.where((number) => number.isEven);
var squaredNumbers = evenNumbers.map((number) => number * number);
var sumOfSquares = squaredNumbers.reduce((a, b) => a + b);
print(sumOfSquares); // 220


List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var sumOfSquares = numbers
	.where((number) => number.isEven)
  .map((number) => number * number<)
  .reduce((a, b) => a + b);
print(sumOfSquares); // 220


List 에 있는 문자열들 중 글자가 5개보다 많은 문자열들만 골라낸 후 모든 글자를 대문자로 바꿔서 반환하고 싶다면 ?

List<String> words = ['apple', 'orange', 'watermelon', 'pineapple'];
var longerThanFiveWords = words.where((word) => word.length > 5);
var result = longerThanFiveWords.map((word) => word.toUpperCase());
print(result); // (ORANGE, WATERMELON, PINEAPPLE)


List<String> words = ['apple', 'orange', 'watermelon', 'pineapple'];
var upperCasedWords = words
    .where((word) => word.length > 5)
    .map((word) => word.toUpperCase());
print(upperCasedWords); // (ORANGE, WATERMELON, PINEAPPLE)


where() + reduce()

List 에 있는 숫자들 중 짝수들만 골라낸 후 그 숫자들을 모두 더한 값을 반환하고 싶다면 ?

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var evenNumbers = numbers.where((number) => number.isEven);
var result = evenNumbers.reduce((a, b) => a + b);
print(result); // 30


List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers
  .where((number) => number % 2 == 0)
  .reduce((a, b) => a + b);
print(result); // 30


List 에 있는 숫자들 중 5 보다 작은 숫자들만 골라낸 후

그 숫자들을 모두 곱한 값을 반환하고 싶다면 ?

List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var smallerThanFive = numbers.where((number) => number < 5);
var result = smallerThanFive.reduce((a, b) => a * b);
print(result); // 24


List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = numbers
  .where((number) => number < 5)
  .reduce((a, b) => a * b);
print(result); // 24


where() + map() + fold()

List 에 있는 숫자들 중 양수들만 골라낸 후 그 숫자들 각각에 10 을 더한 숫자들을 모두 더한 값을 반환하고 싶은 경우

List<int> numbers = [-10, 20, -30, 40, 50];
var positiveNumbers = numbers..where((number) => number > 0);
var plusTenNumbers = positiveNumbers.map((number) => number + 10);
var result = plusTenNumbers.fold(0, (a, b) => a + b);
print(result); // 140

과제 시작

  • 과제를 하면서 git에 익숙해지는 법을 배우는것도 좋다고 말씀하셔서 git 레퍼지토리를 만들어놨다.

중간에 ~ : 최상위 폴더에 git init 을 해서 큰일날뻔 했다.
pwd 현재 폴더를 확인 하는 습관을 만들어야 느꼈다. 😔

0개의 댓글