[Dart/Flutter] 유용한 메서드, 함수 정리

ryan·2021년 8월 20일
2

Dart/Flutter

목록 보기
17/21
post-thumbnail

참고

Dart를 사용하다보면 toList()으로 단짝인 iterable이라는 게 징글징글하게 나온다.
iterable은 반복이 가능한 그룹을 뜻하고, list나, array 등을 의미한다. 참고로, Map은 순서가 없기때문에 iterable이 아니다. 하지만, linked Map은 순서가 있어서, iterable이다.

  • iterable: A collection of values, or "elements", that can be accessed sequentially.

배열의 복사 방법

// ```js말고, ```dart라고 작성해도, 작성하는 페이지 코드에서 
// 예쁜 색깔이 적용이 됐으면 좋겠다. dart를 사용하는데, ```js라고 작성해야하다니... 😥
// ============================================================================

void main() {
  var list = [1, 2, 3, 4];

  // 얕은(주소)복사: 값이 복사되는 게 아니라 원래 reference를 참조해서 map 안의 함수가 연산되서 결과가 나온다
  var newList = list;
  print(newList); // [1, 2, 3, 4]

  // 깊은 복사(spread operator, 스프레드 연산자 활용)
  var spreadList = [10, ...list, 100];
  print(spreadList); // [10, 1, 2, 3, 4, 100]
}

map

map 메서드는 iterable(배열그룹)을 대상으로 forEach를 돌린다.

void main() <{
  var list = [1, 2, 3];
  var newList = list.map((e) => e + 1); // 각 요소(e)에 1을 더한다
  print(list); // [1, 2, 3]
  print(newList); // (2, 3, 4)

  list[0] = 0;

  print(list); // [0, 2, 3]
  print(newList); // (1, 3, 4)

  // 결론은 깊은 복사가 아니라, 얕은 복사가 되고, 항상 newList를 출력할 때마다,
  // list컬렉션에서 (e) => e+1이 연산되서 나온다.

  // Dart의 List는 매개변수, '= '등으로 전달할 때, 메모리 주소 값으로 전달되어서
  // 이름이 다르더라도 한 곳에서 요소를 변경하면 모두 다 변경된다. 그래서 깊은 복사를 하려면
  // 아래, 아래 toList()를 참고
}

asMap

void main() {
  // asMap: 배열 값에 index 키 값을 삽입해서 반환해준다.
  // 키값은 인덱스로 부여되고, 0부터 시작한다.
  
  var words = ['fee', 'fi', 'fo', 'fum'];
  var map = words.asMap();
  print(map); // {0: fee, 1: fi, 2: fo, 3: fum}
  
  print(map[0]! + map[1]!); // feefi
  print(map); // {0: fee, 1: fi, 2: fo, 3: fum}
  print(map.keys.toList()); // [0, 1, 2, 3]
}

toList

toList는 생성되는 값들을 리스트로 만들어서 반환한다. Dart의 List는 매개변수, '= '등으로 전달할 때, 메모리 주소 값으로 전달되어 이름이 다르더라도 한 곳에서 요소를 변경하면 모두 다 변경된다. 그래서 toList를 사용한다.

void main() {
  List orderList = [1, 2, 3];
  // toList() 사용
  List zeroList = orderList.toList();

  for (int i = 0; i < zeroList.length; i++) {
    zeroList[i] = 0;
  }
  print(orderList); // [1, 2, 3] => 원본 배열의 값이 변경되지 않는다.
  print(zeroList); // [0, 0, 0]
}

where

where은 배열 요소를 필터링한다.

void main() {
  var list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  var filterList = list.where((e) => e % 3 != 0); // 배열에서 3의 배수가 아닌 값만 필터링한다.
  print(filterList); // (1, 2, 4, 5, 7, 8, 10)
  print(filterList.toList()); // [1, 2, 4, 5, 7, 8, 10]
  print(filterList.toSet()); // {1, 2, 4, 5, 7, 8, 10}
}

for or forEach

void main() {
  List list = [1, 2, 3, 4];

  // for 문
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
    // 1
    // 2
    // 3
    // 4
  }

  // for in 문(list의 끝까지 반복한다)
  for (int i in list) {
    print(i);
    // 1
    // 2
    // 3
    // 4
  }

  // forEach 문
  list.forEach((e) {
    print(e);
  });
  // 1
  // 2
  // 3
  // 4
}

add, addAll, length, clear

void main() {
  // list 생성자 사용
  var vegetables = List.unmodifiable([]);
  
  // 문자열을 사용하여 list 생성
  var fruits = ['apples', 'oranges'];
  
  // list에 값 추가하기
  fruits.add('bananas');
  print(fruits); // [apples, oranges, banana]
  
  // list에 다수의 요소 추가하기
  fruits.addAll(['grapes', 'watermelons']);
  print(fruits); // [apples, oranges, bananas, grapes, watermelons]
  
  // list의 길이
  print(fruits.length); // 5
  
  // list 단일요소 삭제
  var bananasIndex = fruits.indexOf('bananas');
  print(bananasIndex); // 2
  fruits.removeAt(bananasIndex);
  print(fruits); // [apples, oranges, grapes, watermelons]
  
  // list의 모든 항목 삭제
  fruits.clear();
  print(fruits); // []
}

sort

list에 sort() 메서드를 사용해서 값을 정렬 할 수 있다. 반환 값은 0보다 작거나, 0이거나, 0보다 커야되고, 해당 값을 기준으로 정렬한다. 문자열을 비교하는 경우에는 compareTo() 메서드를 사용한다.

void main() {
  // list 정렬, 숫자
  var sortNumbers = [100, 22, 55, 333, 1, 128, 1024, 32, 989];
  sortNumbers.sort((a, b) => a - b);
  print(sortNumbers); // [1, 22, 32, 55, 100, 128, 333, 989, 1024]

  // list 정렬, 문자
  var sortFruits = [
    'kiwis',
    'bananas',
    'apples',
    'oranges',
    'watermelons',
    'mangos',
    'durians',
  ];
  sortFruits.sort((a, b) => a.compareTo(b));
  print(
      sortFruits); // [apples, bananas, durians, kiwis, mangos, oranges, watermelons]
}

firstWhere

firstWhere는 요소를 반복하고 주어진 조건의 첫 번째 요소를 반환한다.

bool predicate(String element) {
  return element.length > 5;
}

void main() {
  List<String> items = ['Salad', 'Popcorn', 'Toast', 'Lasagne'];

  // 람다식 문법
  // 람다식: 메서드를 하나의 '식(expression)'으로 표현한 것
  String element1 = items.firstWhere((element) => element.length > 5);
  print(element1); // Popcorn

  // 리턴형 문법
  String element2 = items.firstWhere((element) {
    return element.length > 5;
  });
  print(element2); // Popcorn

  // 함수 적용
  String element3 = items.firstWhere(predicate);
  print(element3); // Popcorn

  // orElse, 오.. 이거 신기하네
  String element4 = items.firstWhere(
    (element) => element.length > 10,
    orElse: () => 'None!',
  );
  print(element4); // None!
}

firstWhereindexWhere의 차이점은 firstWhere요소를 반환하고, indexWhere는 일치하는 테스트의 index를 반환하는 것이다.

lastWhere

lastWhere는 요소를 반복하고, 주어진 조건의 마지막 요소를 반환한다.

bool predicate(String element) {
  return element.length > 5;
}

void main() {
  List<String> items = ['Salad', 'Popcorn', 'Toast', 'Lasagne', 'Taco'];

  // 람다식 문법
  String element1 = items.lastWhere((element) => element.length > 5);
  print(element1); // Lasagne

  // 리턴형 문법
  String element2 = items.lastWhere((element) {
    return element.length > 5;
  });
  print(element2); // Lasagne

  // 함수 적용
  String element3 = items.lastWhere(predicate);
  print(element3); // Lasagne

  // orElse, 오.. 이거 신기하네
  String element4 = items.lastWhere(
    (element) => element.length > 10,
    orElse: () => 'None!',
  );
  print(element4); // None!
}

fold

배열의 조건을 누적시켜서 반환한다.

void main() {
  List<int> numbers = [0, 1, 2, 3, 4, 5];

  int sum = numbers.fold(0, (total, element) {
    // 0은 첫번 째로 시작할 값이고, total은 이전에 리턴해 준 값이다.
    // 괄호(기능수행역역) 안에서 반복한다.
    return total + element;
  });
  print(sum);

  // fold메서드가 진행되는 과정
  // index = 0
  // element = 0
  // total = 0
  // return = 0 + 0 => 0

  // index = 1
  // element = 1
  // total = 0
  // return = 0 + 1 => 1

  // index = 2
  // element = 2
  // total = 1
  // return = 1 + 2 => 3

  // index = 3
  // element = 3
  // total = 3
  // return = 3 + 3 => 6
  
  // ...
}

index는 numbers 값의 index 값이고, 첫 번째 파라미터 0번부터 element 자리의 numbers 값을 할당하면서 반복된다. 그리고 total 파라미터 자리에는 이전에 리턴 받은 결과 값이 누적되는 방식이다.

reduce

reduce 메서드는 fold와 큰 차이가 없고, fold에서는 시작 값 0을 지정하는데, reduce에서는 생략한다.

void main() {
  List<int> numbers = [0, 1, 2, 3, 4, 5];

  int sum = numbers.reduce((total, element) {
    return total + element;
  });
  print(sum); // 15

  // 람다식 간소화
  int sum2 = numbers.reduce((total, element) => total + element);
  print(sum2); // 15
}
profile
👨🏻‍💻☕️ 🎹🎵 🐰🎶 🛫📷