먹고 기도하고 코딩하라

Dart에서 리스트 다루기 본문

앱/Flutter

Dart에서 리스트 다루기

사과먹는사람 2021. 10. 4. 22:54
728x90
728x90

 

저번에 '생존을 위한 Dart 톺아보기' 라는 포스팅을 발행했다. 거기서 리스트와 맵, 클래스 개념까지 다루자니 글이 한도끝도없이 길어질 것 같아서 이렇게 새로 쓴다.

다른 데서 '객체'라고 하면 흔히 생각하는 그 자료형이 Dart에도 있다. Map이라는 이름으로. 이 객체와 리스트, 클래스를 많이 쓰니 오늘은 이 얘기를 해보자. 저번과 같이 티스토리 소스 코드는 Dart 언어를 지원하지 않아 엉뚱하게 하이라이팅될 수 있다.

 

 

1-1. 크기 고정 리스트 (fixed length list)

크기가 고정된 리스트는 런타임 동작 시에 길이를 바꿀 수 없다. 리스트를 만들 때 크기를 픽스하려면 다음과 같이 선언하면 된다.

var my_list = new List(3);	// 크기 3짜리 리스트를 만듦
var your_list = List<int>.filled(5, 0);	// 모든 원소가 0으로 초기화된 크기 5짜리 리스트를 만듦

my_list는 크기 3짜리인 리스트인데, 이 리스트는 안 쓴다고 줄어들지 않고 더 쓰겠다고 늘어나지도 않는다. 0번부터 2번까지 쓸 수 있다.

 

1-2. 가변 리스트 (growable list)

가변 리스트는 런타임 동작 시 길이를 바꿀 수 있다. 자유롭게 길이를 정할 수 있는 리스트를 만들려면 다음과 같이 선언하면 된다.

var my_list2 = [1, 2, 3];	// 값과 함께 리스트를 초기화함
var my_list3 = new List();	// 길이가 0인 리스트를 만듦
var my_list4 = new List.empty(growable: true);
var my_list5 = List<int>.filled(5, 0, growable: true);

 

사실 new List(3)처럼 숫자만 달랑 주는 게 아니라면 그 어떤 리스트 생성자라도 가변 리스트로 만들 수 있긴 하다. 바로 growable 옵션을 true로 주는 것이다. List.filled도 마찬가지다. 리스트 생성자에는 위의 것 말고 from, of 등 이터러블 원소들을 가지고 그 값으로 리스트를 만드는 생성자와 generate 생성자 등도 있으니 추가로 확인하기 바란다.

 

1-3. 리스트 원소 접근

리스트의 원소에 접근하는 방법은 간단하다. 리스트 이름 다음 대괄호를 적어주고 그 안에 접근하고 싶은 인덱스 번호를 써주면 된다. 첫 번째 원소와 마지막 원소는 특별히 first, last로 접근이 가능하다. 아쉽게도 파이썬에서 가능한 슬라이싱 연산 같은 건 없는 모양이다.

var my_list5 = List<int>.filled(5, 0, growable: true);
my_list5[0] = 1;
my_list5[4] = 5;
print(my_list5[2]);	// 0
print(my_list5.first);	// 1
print(my_list5.last);	// 5

 

1-4. 리스트 원소 삽입

리스트에 원소를 삽입하려면 add, addAll 등의 메소드를 이용하면 된다. 하나의 값을 리스트 맨 마지막에 추가할 때는 add, 여러 개의 값을 한 번에 추가하려면 리스트에 담아 addAll 하면 된다.

my_list5.addAll([6, 7, 8]);
my_list5.add(9);

특정 위치에 원소를 삽입하고 싶다면 insert를 쓰면 된다. insert()는 첫 번째에 인덱스, 두 번째에 삽입할 데이터를 써 준다. insertAll을 해서 한 번에 여러 데이터를 삽입할 수도 있다.

my_list5.insert(3, 3);
my_list5.insertAll(1, [1, 2]);

 

1-5. 리스트 원소 삭제

리스트 안의 원소를 지우는 방법은 여러 가지가 있다. 값으로 지우는 방법이 있고 인덱스로 지우는 방법도 있으니 두 가지 다 살펴보겠다.

먼저 어떤 값을 지우고 싶다면, remove를 사용하면 된다. remove를 사용하면 리스트의 왼쪽부터 시작해서 처음으로 등장하는 value 값을 삭제한다. remove는 bool 타입을 반환하는데, 해당하는 값이 있었고 잘 지워졌다면 true, 그렇지 않다면 false를 반환한다. 

my_list5.remove(0);	//제일 먼저 등장하는 0 삭제

그 다음 n번 인덱스의 원소 값이 무엇이든 그 인덱스 값을 지우고 싶다면 removeAt을 사용하면 된다. removeAt은 지운 인덱스의 원소를 반환한다.

my_list5.removeAt(3);	// 3번 인덱스의 값을 지운다. 
// 이 때 인덱스는 0번부터 시작하므로 실질적으로 4번째 원소를 지운다는 것을 기억하자

마지막 원소를 지우고 싶다면 removeLast()를 쓸 수 있다. pop과 같은 연산이다. removeLast 역시 방금 지운 원소를 반환한다.

my_list5.removeLast();

어느 범위 사이의 원소를 삭제하고 싶을 수도 있다. 그럴 때는 removeRange를 사용할 수 있다. removeRange는 start와 end 인덱스를 받아 start, end 사이의 원소를 모두 삭제한다. 아무것도 반환하지 않는다.

my_list5.removeRange(1, 3);
// 1번부터 3번 인덱스 전까지, 즉 1번과 2번 2개의 원소를 삭제한다.

리스트의 전체 원소를 삭제하고 싶다면 clear()를 사용하면 된다. 리스트 안의 원소가 지워져 리스트는 길이가 0이 된다.

my_list5.clear();

 

1-6. 리스트 원소 검색

리스트가 어떤 원소를 갖고 있는지 확인하고 싶다면, contains 메소드를 쓸 수 있다. contains(value)를 하면 value가 들어있을 때 true, 그렇지 않을 때 false를 반환한다.

my_list5.contains(0);	//true

 

리스트 안에 있는 원소 중 어떤 하나라도 주어진 조건을 만족하는지 알고 싶다면 any를 쓸 수 있다. 다음의 코드는 my_list5의 원소 중 5가 넘는 값이 하나라도 있는지 확인하는 문장이다. 이와 같이 any 안에 bool 타입을 반환하는 함수를 써서 구현할 수 있다. every도 마찬가지다. 특이한 건 함수 안의 매개변수가 하나라도 반드시 괄호 ()로 감싸줘야 한다는 사실이다.

print(my_list5.any((x) => x > 5));
print(my_list5.every((x) => x < 6));

어떤 원소가 여러 개 있는 것 같을 때, 가장 왼쪽에 있는 값을 찾을 때는 indexOf를 쓸 수 있다. 해당 원소를 가진 제일 처음 나오는 인덱스 번호가 반환된다.

my_list5.indexOf(0);

마찬가지로 뒤에서부터 찾고 싶을 때는 lastIndexOf를 쓸 수 있다.

my_list5.lastIndexOf(0);

 

1-7. 리스트의 쓸 만한 속성과 메소드들

  • isEmpty : 리스트가 비었다면 true, 그렇지 않다면 false를 반환한다.
  • isNotEmpty : 리스트가 비어 있지 않다면 true, 비었다면 false를 반환한다.
  • length : 리스트의 길이를 반환한다.
  • reversed : 리스트의 값을 거꾸로 뒤집은 리스트를 반환한다.

 

  • .toString() : 리스트를 print하는 등 문자열로 나타낼 필요가 있을 때 사용하는 메소드이다. String 타입을 반환한다.
  • .toSet() : 리스트를 set 자료형으로 바꿔준다. Set<E> 타입을 반환한다.
  • .sort() : 리스트를 정렬한다. 반환형은 void이고, 리스트 그 자체를 정렬하는 메소드라는 데 주의하자. 정렬 함수를 넣어줄 수도 있는데, 정렬 함수가 따로 없다면 알파벳은 A-Za-z 순으로, 숫자는 0-9 순으로 오름차순 정렬된다.
  • .shuffle() : 리스트를 무작위로 섞는다. Random 타입의 인자를 seed로 줘서 섞을 수 있다. 반환형은 따로 없고 리스트 원본을 변형시키는 메소드이다.
  • .replaceRange(start, end, [replacemenets]) : 리스트의 start부터 end까지 [replacements]로 변경하는 메소드이다.
  • reduce() : reduce 메소드 안에 주어진 함수를 사용해 리스트 안의 원소를 연산해 하나의 값을 만드는 메소드이다. E 타입을 반환하고, 주로 int형 리스트 등에서 주어진 값을 모두 더하는 데에 쓰인다.
print(my_list5.reduce((a, x) => a += x));
  • map() : map 메소드 안에 주어진 함수를 리스트 안의 원소 각각에 연산한 결과를 새로운 리스트에 담아, 그 결과 리스트를 반환하는 함수이다. 아래 예시는 my_list5 안의 모든 원소에 2를 곱한 새로운 리스트를 반환한다.
  • my_list5.map((x) => x * 2);
  • .join(String) : 리스트 안의 원소를 separator로 연결해 문자열로 반환하는 함수이다. 만약 separator가 없다면 그냥 쭉 이어붙여서 String 타입으로 반환한다.
  • forEach(function) : 리스트 안의 원소를 대상으로 매개변수로 주어진 함수를 실행하는 함수이다. 다른 프로그래밍 언어의 forEach와 기능은 동일하다.
  • fillRange(start, end, [fillValue]) : 리스트의 start부터 end 인덱스까지 fillValue로 전부 덮어쓰는 함수이다. 

 

소개하지 않은 리스트 메소드가 있으므로 더 자세한 메소드와 프로퍼티를 보고 싶다면 공식 문서를 참고하면 좋겠다.

 

 

 

References

 

 

728x90
반응형
Comments