Dart 기본 문법 08

GreenBean·2023년 4월 4일
0
post-thumbnail

Dart

Dart 공식문서
다트 ( Dart ) 컬렉션
다트 ( Dart ) 제너릭 개념

Dart 의 컬렉션

  • 컬렉션은 다수의 데이터를 처리할 수 있는 자료구조
    • 하나의 데이터가 아닌 데이터의 집합이기 때문에 반복 가능
    • 반복 가능하다는 의미를 단순하게 생각하면 반복문 내에서 순회할 수 있다는 것
  • 다트에서는 자체적으로 세 가지 컬렉션을 제공
    • List : 데이터 순서가 있고 중복 허용
    • Set : 데이터 순서가 없고 중복 허용하지 않음
    • Map : 키 ( key ) 와 값 ( value ) 으로 구성되며 키는 중복되지 않고 값은 중복 가능
  • 보통 컬렉션의 기본 중의 기본은 배열 ( array )
    • 그러나 다트에서는 List 가 곧 배열

List

# List

// List<데이터 타입> 변수명 = [데이터1, 데이터2, 데이터3, ...];

List<String> colors = ["Red", "Orange", "Yellow"];

// List<데이터 타입> 변수명 = List();
// 변수명.add(데이터1);
// 변수명.add(데이터2);
// 변수명.add(데이터3);

List<String> colors = List();
colors.add("Red");
colors.add("Orange");
colors.add("Yellow");
  • List 는 데이터를 여러 개 담을 수 있는 자료구조
    • 데이터를 List 에 담을 때 순서를 가지기 때문에 배열을 대체할 수 있고 데이터에 순차적으로 접근하기 쉬움
  • 위 코드에서는 List 에 들어갈 데이터 타입을 String 으로 지정
    • 그런데 만약에 List 에 여러 타입의 데이터를 섞어서 넣고 싶으면 어떻게 해야 할까?
      • 다트의 변수에서 배웠던 타입 추론 키워드인 dynamic 이나 var 를 사용하면 딤
# 예시

main() {
  List<dynamic> list1 = [1, 2.5, "test"];
  dynamic list2 = [1, 2.5, "test"];
  list2 = 1;
  var list3 = [1, 2.5, "test"];
  // list3 = 1; error
  
  for (int i = 0; i < list1.length; i++) {
    print(list1[i]);
  }
}

------------------------------------------------------------------------------------------

# 결과

1
2.5
test
  • Line 2 를 보면 list1 의 타입은 List<dynamic>
    • 이것은 List 에 들어가는 데이터 타입이 dynamic 이라는 의미
    • 이렇게 사용하면 dynamic 은 미지정 타입이고 타입 변경도 가능하기 때문에 list 의 데이터로 다양한 타입을 넣을 수 있음
  • Line 3 과 같이 list2 의 타입을 dynamic 으로 하면 list2 의 데이터를 보고 list2 의 타입을 추론할 것
    • 이때 추론되는 타입은 list1 처럼 List<dynamic> 이 될 것
  • Line 4 는 dynamic 타입인 경우에는 타입 변경이 가능하기 때문에 List<dynamic> 타입으로 추론되었을 list2 에 정수 1 을 할당하면 int 형으로 다시 재지정될 것
    • 에러 없이 잘 실행됨
  • Line 5 와 같이 var 타입을 사용해도 무방
    • var 역시 dynamic 과 같이 타입 미지정인 상태이고 list3 에 할당된 List 의 형태를 보면 타입을 List<dynamic> 으로 추론하여 지정될 것이기 때문
    • 단 list3 에 정수 1 을 할당하려고 하면 타입 변경을 시도하는 것이기 때문에 에러가 발생
  • List 의 각 데이터에 접근하려면 인덱스를 사용하면 됨
    • 예를 들어 list1 의 첫번째 요소 ( element ) 에 접근하려면 list1[0]
      • 인덱스는 0 부터 시작
    • List 는 순서가 있는 데이터의 집합이기 때문에 for 문을 이용하면 순차적으로 데이터에 접근 가능
  • Line 8 을 보면 for 문을 이용하여 list1 의 데이터를 출력하고 있음

    • 이 때 인덱스의 범위를 i < list1.length 로 지정
      • list1.length 는 list1 의 크기를 나타냄
      • 크기는 list1 에 포함된 요소의 수
  • 리스트에서 사용되는 주요 메서드와 프로퍼티는 다음과 같음

    • indexOf(요소) : 요소의 인덱스 값
    • add(데이터) : 데이터 추가
    • addAll([데이터1, 데이터2]) : 여러 데이터 추가
    • remove(요소) : 요소 삭제
    • removeAt(인덱스) : 지정한 인덱스의 요소 삭제하고 해당 요소 리턴
    • contains(요소) : 요소가 포함되었으면 true 아니면 false
    • clear() : 리스트 요소 전체 삭제
    • sort() : 리스트 요소 정렬
    • first : 리스트 첫 번째 요소
    • last : 리스트 마지막 요소
    • reversed : 리스트 요소 역순
    • isNotEmpty : 리스트가 비어있지 않으면 true 비어있으면 false
    • isEmpty : 리스트가 비었으면 true 비어있지 않으면 false
    • single : 리스트에 단 1개의 요소만 있다면 해당 요소 리턴
# 예시

main() {
  List<dynamic> list = [1, 2.5, "test"];
  
  print("index of test = ${list.indexOf("test")}"); // "test" 의 인덱스 값 출력
  
  list.add("new"); // "new" 추가
  list.addAll([100, "korea"]); // 여러 요소 추가
  list.remove(2.5); // 요소 중 2.5 삭제
  list.removeAt(0); // 인덱스 0의 요소(=1) 삭제
  
  print("-----Start of list-----");
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
  }
  print("-----End of list-----");
  
  print("first of list = ${list.first}");
  print("last of list = ${list.last}");
  print("reverse of list = ${list.reversed}");
  
  if (list.contains("new")) {
    print("There is new");
  }
  
  if (list.isNotEmpty){
    print("list is not empty");
  }
  
  list.clear(); // 리스트 모든 항목 삭제
  for (int i = 0; i < list.length; i++) {
    print(list[i]);
  }
  
  if (list.isEmpty) {
    print("list is empty");
  }
  
  list.add(1000); // 1000 추가
  
  // 리스트의 요소가 단 1개라면 해당 요소 리턴
  print("list has just one element = ${list.single}");
  
  list.addAll([100, 20, 1, 200, 5, 3, 30, 2000]);
  list.sort(); // 리스트 정렬
  print(list);
}

------------------------------------------------------------------------------------------

# 결과

index of test = 2
-----Start of list-----
test
new
100
korea
-----End of list-----
first of list = test
last of list = korea
reverse of list = (korea, 100, new, test)
There is new
list is not empty
list is empty
list has just one element = 1000
[1, 3, 5, 20, 30, 100, 200, 1000, 2000]

Set

# Set

// Set<데이터 타입> 변수명 = {데이터1, 데이터2, 데이터3, ...};

Set<String> colors = {"Red", "Orange", "Yellow"};

// Set<데이터 타입> 변수명 = Set();
// 변수명.add(데이터1);
// 변수명.add(데이터2);
// 변수명.add(데이터3);

Set<String> colors = Set();
colors.add("Red");
colors.add("Orange");
colors.add("Yellow");
  • Set 은 데이터를 여러 개 담을 수 있는 자료구조인 것은 List 와 동일
    • 하지만 데이터의 순서가 없고 중복된 요소를 허용하지 않음
  • SetList 와 거의 유사한 형태
    • 주의할 점은 초기값을 넣을 때 List[] 를 사용했지만 Set{} 를 사용
    • 또한 중복을 허용하지 않기 때문에 같은 값을 여러 번 추가해도 단 하나만 존재
# 예시

main() {
  Set<dynamic> testSet = {1, 2.5, "test"};
  testSet.add(1);
  testSet.add(1);
  testSet.add(1);
  testSet.add(3);
  testSet.add(2);
  testSet.add("korea");
  testSet.add("korea");
  testSet.add("korea");
  
  print("-----Start of testSet-----");
  for (dynamic each in testSet) {
    print(each);
  }
  print("-----End of testSet-----");
}

------------------------------------------------------------------------------------------

# 결과

-----Start of testSet-----
1
2.5
test
3
2
korea
-----End of testSet-----
  • 순서를 가지지 않기 때문에 각 요소에 인덱스로는 접근하지 못하지만 for .. in 문을 통해 접근 가능
    • for .. in 문은 반복 시 in 뒤에 선언된 객체에서 하나의 요소를 가져와 in 앞에 선언된 변수에 할당
  • Set 의 메서드와 프로퍼티는 List 와 겹치는 부분이 많지만 인덱스와 관련된 것은 사용하지 않음
    • Set 은 데이터 순서를 가지지 않기 때문
    • 다음의 메서드와 프로퍼티는 사용 불가
      • indexOf()
      • removeAt()
      • sort()
      • reversed
# 예시

main() {
  Set<dynamic> testSet = {1, 2.5, "test"};
  // print("index of test = ${testSet.indexOf("test")}"); error
  testSet.add("new"); // "new" 추가
  testSet.addAll({100, "korea"}); // 여러 요소 추가
  testSet.remove(2.5); // 요소 중 2.5 삭제
  // testSet.removeAt(0); error
  
  print("-----Start of testSet-----");
  print(testSet);
  print("-----End of testSet-----");
  
  print("first of testSet = ${testSet.first}");
  print("last of testSet = ${testSet.last}");
  // print("reverse of testSet = ${testSet.reversed}"); error
  
  if (testSet.contains("new")) {
    print("There is new");
  }
  
  if (testSet.isNotEmpty) {
    print("testSet is not empty");
  }
  
  testSet.clear(); // Set 모든 항목 삭제
  print(testSet);
  
  if (testSet.isEmpty) {
    print("testSet is empty");
  }
  
  testSet.add(1000); // 1000 추가
  
  // Set 의 요소가 단 1개라면 해당 요소 리턴
  print("testSet has just one element = ${testSet.single}");
  
  testSet.addAll([100, 20, 1, 200, 5, 3, 30, 2000]);
  // testSet.sort(); error
  print(testSet);
}

------------------------------------------------------------------------------------------

# 결과

-----Start of testSet-----
{1, test, new, 100, korea}
-----End of testSet-----
first of testSet = 1
last of testSet = korea
There is new
testSet is not empty
{}
testSet is empty
testSet has just one element = 1000
{1000, 100, 20, 1, 200, 5, 3, 30, 2000}

Map

# Map

// Map<키 타입, 값 타입> 변수명 = {
//   키1: 값1,
//   키2: 값2,
//   키3: 값3,
// }

Map<int, String> testMap = {
  1: "Red",
  2: "Orange",
  3: "Yellow",
}

// Map<키 타입, 값 타입> 변수명 = Map();
// 변수명[키1] = 값1;
// 변수명[키2] = 값2;
// 변수명[키3] = 값3;

Map<int, String> testMap = Map();
testMap[1] = "Red";
testMap[2] = "Orange";
testMap[3] = "Yellow";
  • Map 은 키와 값으로 이뤄진 것이 가장 큰 특징
    • 키와 값은 한 쌍으로 이뤄짐
    • 키에 대한 값이 매칭되어 있어서 빠른 탐색이 가능
  • 맵은 순서를 가지지 않지만 키를 정수로 설정하면 순서를 가진 것처럼 사용할 수도 있음
    • 키는 중복이 불가하고 값은 중복 가능

# 예시

main() {
  Map<int, String> testMap = {
    1: "Red",
    2: "Orange",
    3: "Yellow",
  };
  testMap[4] = "Green";
  
  print(testMap);
  print(testMap[1]);
  print(testMap[5]);
}

------------------------------------------------------------------------------------------

# 결과

{1: Red, 2: Orange, 3: Yellow, 4: Green}
Red
null
  • Line 7 은 새로운 키인 4 에 새로운 값 Green 을 추가하는 것
  • Line 10 은 키 1 의 값인 Red 를 가져와서 출력하는 것
  • Line 11 처럼 존재하지 않는 키인 5 의 값을 가져오려고 하면 null 을 리턴
  • map 에서 키에 대한 값의 맵핑을 새로운 값으로 변경하려면 update() 라는 메서드를 이용하면 됨
# 예시

main() {
  Map<int, String> testMap = {1: "Red", 2: "Orange", 3: "Yellow",};
  testMap[4] = "Green";
  
  testMap.update(1, (value) => "NewRed", ifAbsent: () => "NewColor");
  testMap.update(5, (value) => "NewBlue", ifAbsent: () => "NewColor");
  
  print(testMap[1]);
  print(testMap[5]);
  
  print(testMap);
}

------------------------------------------------------------------------------------------

# 결과

NewRed
NewColor
{1: NewRed, 2: Orange, 3: Yellow, 4: Green, 5: NewColor}
  • Line 5 는 키 1 의 값을 NewRed 바꾸는 것
    • ifAbsent 는 변경하고자 하는 키가 없을 때 해당 키와 값을 추가하도록 설정하는 것
  • Line 6 을 보면 키 5 는 존재하지 않음
    • 따라서 키 5 가 추가되면서 값은 ifAbsent 에서 지정한 NewColor 가 됨
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글