Dart

Dart 프로그래밍 기초 - #5. 컬렉션 Collection

아크로코드 2024. 10. 7. 19:00

같은 타입의 여러 데이터를 한꺼번에 효율적으로 관리하기 위해서는 Collection을 사용하면 좋습니다. Dart의 주요 컬렉션 타입에는 List, Set, 그리고 Map이 있습니다. 각각의 컬렉션이 어떤 역할을 하고, 어떻게 사용하는지 예시를 통해 쉽게 설명해드릴게요.
 

List: 순서가 있는 데이터의 모음

List는 말 그대로 "목록"을 의미합니다. Dart의 List는 순서가 있는 데이터의 집합을 나타내며, 배열과 유사한 기능을 합니다. (Dart에서는 배열이 따로 없고, 배열의 모든 역할을 List로 대체합니다.) 각 요소는 인덱스로 접근할 수 있습니다. List 대괄호[ ]로 요소들을 감싼 형태로 선언합니다.
 

 
위 코드에서 numberList라는 변수를 선언했습니다. 선언된 numberList의 타입을 확인해보면 List<int>라는 것을 볼 수 있습니다. 이렇게 Collection에 대해서도 타입 추론이 되며, 리스트를 이루고 있는 요소들의 공통적인 타입으로 추론을 하게 됩니다. 리스트를 이루는 요소들이 서로 다른 타입이 섞여 있다면 모든 타입의 부모 역할을 하는 Object로 추론되어 List<Object>로 타입 추론이 됩니다.

List<int>에서 <int>에 해당하는 부분을 Generic이라고 합니다.

 
numberList.length로 리스트에 몇 개의 요소들이 있는지를 확인할 수 있습니다. 또한 첫 번째 요소에 접근할 때 numberList[0]와 같이 대괄호와 숫자(index)로 접근을 합니다. 

프로그래밍에서는 첫 번째 요소를 1이 아닌 0으로 접근하는 방식을 사용하고 있습니다. 첫 번째, 두 번째, 세 번째, 네 번째가 각각 0, 1, 2, 3... 과 같은 순서로 사용하면 됩니다.

 

 
List의 기본적인 연산을 살펴봅시다.
4번 라인과 같이 List에 요소를 추가하려면 add() 함수를 사용할 수 있습니다. 이 때 요소는 가장 마지막에 추가됩니다. index와 요소의 쌍이 `0=수학, 1=영어, 2=과학, 3=경제`와 같이 3번 index에 추가가 됩니다.
 
7번 라인에서는 List 내의 요소를 수정하고 있습니다.
 
10번 라인에서는 remove() 함수로 특정 index의 요소를 제거합니다. remove() 함수는 제거한 요소를 리턴하기 때문에 새로운 변수에 다시 해당 참조값을 할당할 수 있습니다.
 
14, 15번 라인에서는 List의 first, last라는 프로퍼티property로 첫 번째와 마지막 요소에 접근할 수 있습니다. (내부적으로 getter method로 되어있습니다)
 
17번 라인의 contains() 함수는 List 전체를 돌면서 파라미터로 들어온 요소가 일치하는 것이 있는지를 확인하고, 같은 것이 있으면 true를, 아니면 false를 리턴합니다.
 

List와 반복문

 
List에 담긴 요소에 대해서 반복문을 많이 쓰게 됩니다. index에 따라서 로직이 달라져서 index가 꼭 필요한 반복문이라면 3~5번 라인과 같은 for문을 사용하는게 좋지만, 많은 경우에 index가 굳이 필요하지 않은 반복문을 사용하게 됩니다. 이럴 때는 7~9번 라인처럼 for-in문을 통해서 반복을 할 수 있습니다. 이럴 경우에 man에 해당하는 부분은 0번 index부터 마지막 index의 요소까지를 순차적으로 꺼내온 값입니다.
 

Set 중복이 없는 데이터의 모음

Set은 중복을 허용하지 않는 데이터의 집합입니다. 같은 값이 여러 번 들어가도 한 번만 저장됩니다. 예를 들면, Set을 사용하여 여행 가본 나라들을 관리하는 코드를 작성해볼 수 있습니다. 이 코드는 중복된 나라가 추가되지 않으며, Set의 기본 특성인 중복 제거와 고유한 값 저장 기능을 활용합니다.

 

 

3번 라인에서 Set<String>으로 여행 가본 나라들을 visitedCountries 변수에 저장합니다. 선언할 때는 중괄호로 요소들을 감싸서 처리합니다.

6, 7, 10번 라인에서 처럼 새로운 요소들을 add()로 추가할 수 있습니다. 그런데 10번 라인에서처럼 이미 있는 요소를 추가하게 되면, 따로 추가되지 않습니다.

14번 라인은 contains()라는 함수로 visitedCountries 내에 특정 요소가 포함되어 있는지를 확인할 수 있습니다.

21번 라인에서 List 타입과 마찬가지로 length 프로퍼티로 몇 개의 요소가 있는지를 확인할 수 있습니다.

25~27번 라인에서 for in loop로 요소들에 대한 반복문을 실행할 수 있습니다.

 

Map 키와 값의 쌍으로 구성된 데이터

Map은 특정 키(Key)에 대응되는 값을 저장하는 컬렉션입니다. 일종의 사전(dictionary)처럼 키를 사용해 값을 검색할 수 있습니다. Map을 사용하여 지역 이름과 해당 지역의 전화번호를 연결하는 예제를 만들어볼 수 있습니다.

 

 

3번 라인에서 지역 이름과 해당 지역의 전화번호를 areaCodes 변수에 저장합니다. 이 때, 중괄호로 전체를 감싸고, 키와 값을 콜론(:)으로 나누어서 선언합니다.

16번 라인에서는 특정 키에 대한 값을 가져오고 있습니다. 대괄호[]로 접근해서 특정 지역의 전화번호를 출력할 수 있습니다. 만약에 areaCodes에 없는 키에 대한 값을 가져오려고 한다면 null을 가져오게 됩니다.

19번 라인에서는 새로운 키-값 쌍을 저장하거나 기존에 있던 키에 대한 값을 수정하고자 할 때의 예시를 보여주고 있습니다.

23번 라인에서는 조금 더 안전하게 키가 있는지 체크를 하고 가져오기 위해서 containsKey() 함수를 호출해서 확인하고 있습니다.

31번 라인에서 forEach() 함수는 반복문을 실행할 수 있는 함수인데요, key, value가 클로저의 파라미터로 존재하는 것을 볼 수 있습니다.

 

Set, Map을 돌렸을 때는 일반적으로 순서가 보장되지 않고, 순서에 대한 보장이 필요하면 dart:collection 패키지의 여러 클래스들을 활용할 수 있습니다.