[Flutter/Dart] List를 밥아저씨처럼 알잘딱깔센 정리해보기

Hans Park·2022년 1월 23일
0

Flutter

목록 보기
8/14
post-thumbnail
post-custom-banner

오늘은 Dart의 List 컬렉션을 알잘딱깔센으로 잘 사용해보기로 하자.

https://api.dart.dev/stable/2.15.1/dart-core/List-class.html

List?

리스트는 데이터를 순차적으로 담을 수 있는 인덱싱 가능한 자료구조이다.
배열을 대체할 수 있다.

서브클래스로 Fixed-length list와 Growable list가 있는데,
말 그대로 Fixed-length list는 길이가 고정된 list이고,
Growable list는 아이템에 따라 길이가 조정된다.

Constructor

defalut

보통 아래와 같이 간단하게 사용한다.
Growable list이다.

void main() {
  List<int> l  = [];
  print(l);
}

//result
[]

filled

filled 생성자를 사용하여, 길이와 그 길이를 채울 값을 지정해줄 수 있다.

이때, growable이 false면 (따로 설정하지 않으면 false이다) Fixed-length list,
true이면 Growable list이다.

void main() {
  var l1 = List.filled(10, 1, growable : true);
  l1.add(3);
  print(l1);
  
  var l2 = List.filled(10, 1);
  //l1.add(3);  Error
  //print(l1);
}

//reseult
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3]

empty

empty 생성자를 사용하여, 빈 리스트를 생성할 수 있다.

이때, growable이 false면 (따로 설정하지 않으면 false이다) Fixed-length list,
true이면 Growable list이다.

void main() {
  var l1 = List.empty(growable : true);
  l1.add(3);
  print(l1);
  
  var l2 = List.empty(growable : false);
  //l1.add(3);  Error
  //print(l1);
}

//reseult
[3]

empty

empty 생성자를 사용하여, 빈 리스트를 생성할 수 있다.

이때, growable이 false면 (따로 설정하지 않으면 false이다) Fixed-length list,
true이면 Growable list이다.

void main() {
  var l1 = List.empty(growable : true);
  l1.add(3);
  print(l1);
  
  var l2 = List.empty(growable : false);
  //l1.add(3);  Error
  //print(l1);
}

//reseult
[3]

기타 다른 정보는 공식문서를 확인하자.
https://api.dart.dev/stable/2.15.1/dart-core/List-class.html


Properties

자주 쓰이는 것만 정리해보았다.

first

리스트의 첫번째 원소를 반환한다.

isEmpty, isNotEmpty

각각 리스트가 비었는지, 비어있지 않은지 확인하여 true/false를 반환한다.

last

리스트의 마지막 원소를 반환한다.

length

리스트의 길이를 반환한다.


Methods

마찬가지로 중요하거나 자주 쓰이는 것을 정리해보았다.

add(E value) -> void

리스트 마지막에 원소를 추가한다.

clear() → void

리스트의 원소들을 전부 삭제한다.

void main() {
  var l1 = [];
  l1.add(1);
  l1.add(2);
  l1.add(3);
  l1.add(4);
  l1.clear();
  print(l1);
}

//result
[]

forEach(void action(E value)) -> void

리스트 내부 원소들이 value로 순서대로 주어지고, action함수를 반복호출한다.

void main() {
  var l1 = [];
  l1.add(1);
  l1.add(2);
  l1.add(3);
  l1.add(4);
  l1.forEach((value) {print(value);});
}

//result
1
2
3
4

fold < T >(T initialValue, T combine(T previousValue, E element)) -> T

forEach같은 반복문이지만, 이전 함수의 return값을 사용할 수 있다.
initialValue는 시작할 원소의 값이다.

void main() {
  List<int> l1 = [];
  l1.add(1);
  l1.add(2);
  l1.add(3);
  l1.add(4);
  l1.add(5);
  l1.add(6);
  l1.add(7);
  l1.add(8);
  l1.add(9);
  l1.add(10);
  
  int answer = l1.fold(0, (vTotal, value){
     return vTotal + value;
  });
  print(answer);
  int answer2 = l1.fold(1, (vTotal, value){
     return vTotal + value;
  });
  print(answer2);
}

//result
55  //(0(initialValue) + 1 + ... + 10)
56  //(1(initialValue) + 1 + ... + 10)

reduce(E combine(E vTotal, E element)) → E

fold 메소드에서 initialValue가 없는 버전이다.
처음엔 첫번째 원소가 vTotal로 들어오고, 두번째 원소부터 element를 통해 시작된다.
그 이후론 fold와 같이 이전 return값이 vTotal로 들어온다.

void main() {
  List<int> l1 = [];
  l1.add(1);
  l1.add(2);
  l1.add(3);
  l1.add(4);
  l1.add(5);
  l1.add(6);
  l1.add(7);
  l1.add(8);
  l1.add(9);
  l1.add(10);
  
  int answer = l1.fold(0, (vTotal, value){
  	 print("vTotal = $vTotal  |  value = $value");
     return vTotal + value;
  });
  print(answer);
}

//result
vTotal = 1  |  value = 2
vTotal = 3  |  value = 3
vTotal = 6  |  value = 4
vTotal = 10  |  value = 5
vTotal = 15  |  value = 6
vTotal = 21  |  value = 7
vTotal = 28  |  value = 8
vTotal = 36  |  value = 9
vTotal = 45  |  value = 10
55

remove(Object? value) → bool

리스트를 순서대로 접근하면서 가장 처음 만나는 value값을 지운다.

sort([int compare(E a, E b)?]) → void

sort함수를 통해 리스트를 정렬할 수 있다.

void main() {
  List<int> l1 = [];
  l1.add(121);
  l1.add(232);
  l1.add(3343);
  l1.add(14);
  l1.add(54);
  l1.add(66);
  l1.add(74);
  l1.add(89);
  l1.add(933);
  l1.add(44410);
  l1.sort();
  print(l1);
}

//result
[14, 54, 66, 74, 89, 121, 232, 933, 3343, 44410]

sort함수 매개변수로 compare를 보내면 custom이 가능하다.

void main() {
  List<int> l1 = [];
  l1.add(121);
  l1.add(232);
  l1.add(3343);
  l1.add(14);
  l1.add(54);
  l1.add(66);
  l1.add(74);
  l1.add(89);
  l1.add(933);
  l1.add(44410);
  l1.sort((a, b){return (a > b)? -1:1;});
  print(l1);
}

//result
[44410, 3343, 933, 232, 121, 89, 74, 66, 54, 14]

spread operator

Dart에서는 리스트 이어붙히기가 가능하다

void main() {
  var l1 = [1,2,3];
  var l2 = [0, ...l1];
  var l3 = [0,l1];
  print(l1);
  print(l2);
  print(l3);
}


//result
[1, 2, 3]
[0, 1, 2, 3]
[0, [1, 2, 3]]

Cascade notation

Dart에서는 하나의 클래스에 인스턴스 변수 접근, 메소드 호출 등을 한번에 할 수 있다.

공식문서에 따르면, 캐스케이드(.., ?..)를 사용하면 동일한 개체에 대해 일련의 작업을 수행할 수 있습니다. 함수 호출 외에도 동일한 개체의 필드에 액세스할 수도 있습니다. 이렇게 하면 임시 변수를 생성하는 단계를 줄일 수 있고 보다 유동적인 코드를 작성할 수 있습니다.고 한다.

Before

var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;

After

var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

이처럼 지역변수 사용을 줄일 수 있다.

또한, 경우에 따라 명령어 전체의 길이도 줄일 수 있다.

Before

final addressBook = AddressBookBuilder();
addressBook.name = 'jenny';
addressBook.email = 'jenny@example.com';

addressBook.phone = PhoneNumberBuilder();
addressBook.phone.number = '415-555-0100';
addressBook.phone.label = 'home';
addressBook.phone.build();

addressBook.build();

After

final addressBook = (AddressBookBuilder()
        ..name = 'jenny'
        ..email = 'jenny@example.com'
        ..phone = (PhoneNumberBuilder()
                    ..number = '415-555-0100'
                    ..label = 'home').build())
        .build();



주의할 점은 오브젝트를 반환하는 함수에서만 사용이 가능하다.

var sb = StringBuffer();
var returnWrite = sb.write('foo');  //write에서 리턴되는 변수는 없기때문에 1차 문제가 되고
// write함수에서 리턴된 변수의 없는 멤버 write라는 함수에 접근하려고 하니 에러가 발생한다.
returnWrite.write('bar');  //?????

만약 위의 코드를 제대로 사용하려면 아래와 같이 구성하면 된다.

var sb = StringBuffer()
           ..write('foo')
           ..write('bar');

https://dart.dev/guides/language/language-tour#cascade-notation-


정리

자주 쓰이는 함수와 유용하게 사용했던 함수들 위주로 정리해보았다.
Dart가 워낙 공식문서를 잘 만들어두긴 했지만, 페이지도 여러 개이며 키워드를 모르면 찾기 힘든 편이다.
가끔씩 이 포스팅처럼 자주쓰는 명령어나 함수를 정리하는 시간도 가져보면 좋을 것 같다.

출처

profile
장안동 개발새발
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 1월 23일

c++의 container와 비슷하면서도 신기한 기능이 많네요🤭 잘 보고 갑니다!

답글 달기