Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

건축과컴퓨터

[C# - basic] tuple 본문

C# for Grasshopper

[C# - basic] tuple

2021. 1. 9. 16:52

array, list 글들에서는 학생들의 점수를 받아서 그 중 재시험을 보아야 하는 학생이 몇 명이나 있는지 찾아내는 문제를 다루었다. 여기서 문제를 조금 바꿔보자. 학생들의 점수 뿐만 아니라 학생들의 이름까지 주어졌다고 할때, 재시험을 보아야 하는 학생들의 목록을 뽑아내는 건 어떻게 할까?

 

아래의 코드를 보자.

 

1
2
3
4
5
6
7
8
9
10
List<int> scores = new List<int> { 991366823 };
List<string> names = new List<string> { "Alice""Betty""Charlie""David""Emily" };
 
List<string> examAgainList = new List<string>();
 
for (int i = 0; i < scores.Count; i++)
{
    if (scores[i] <= 50)
        examAgainList.Add(names[i]);
}
cs

 

1, 2: scores, names라는 리스트가 주어져있고,

4: examAgainList라는, 이름을 넣을 빈 리스트를 만든 다음에,

6: for문을 돌면서

8: 점수가 50점 이하면

9: 재시험을 볼 사람의 이름을 리스트에 더한다.

 

이렇게 코드를 짜면 작동을 잘 하긴 할텐데, 그래도 영 찝찝한 구석이 조금 있다. 만약 여기에 시험 점수 40점을 받은 Frank가 새로 추가된다고 하자. 그러면 코드를 관리하는 사람은 score에 가서 40을 넣어주고, names에 가서 Frank를 넣어주어야 한다. 그런데 실수로 점수는 넣어주었는데 이름을 까먹고 안 넣어주었다고 하자. 그러면 무슨 일이 일어날까? 아마 scores는 크기 6짜리인 리스트고, names는 크기 5짜리인 리스트인데, 하필 scores[5]에 들어있는 점수가 재시험에 해당하는 점수라 names[5]를 리스트에 더해주려다가, names[5]는 인덱스를 벗어난 값이어서 에러가 날 것이다. 이렇게 에러를 찾아낸 상황이면 그나마 바로 대응할 수 있어서 다행이다. 만약 이름 넣는 걸 한 번 잊어버리고 나서 뒤에 다른 점수-사람들은 제대로 입력했다면? Frank부터의 학생들은 점수가 한 칸씩 밀린 것이 되어서 재시험 대상 리스트에는 잘못된 재시험 대상자들이 쭉 들어가게 된다.

 

이 상황에서 필요한 건, scores와 names와 같이 독립적으로 존재하는 리스트가 아니라, 같이 관리되는 하나의 리스트다. 필요한 정보들을 순서쌍으로 저장하는 방법은 없을까? 이런 상황에서 간단하게 쓸 수 있는 것이 바로 tuple이다.

 

Tuple(튜플, 터플)

열거, 순서쌍 이라고도 하는 것 같은데, 정확히 대응되는 개념은 아닌 듯하다. 공식 문서에는 튜플이라고 표기되어 있는데, 터플이라고 읽는 사람들도 드물게 본 적이 있다. 앞으로의 글들에서는 튜플이라고 쓰도록 하겠다.

튜플은 여러 타입들을 순서쌍처럼 그룹지어주는 데에 쓰인다. 아래의 공식 문서에서 자세한 내용을 볼 수 있다.

https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-tuples

 

튜플 형식 - C# 참조

C# 튜플 알아보기: 관련 데이터 요소를 느슨하게 그룹화하는 데 사용할 수 있는 간단한 데이터 구조

docs.microsoft.com

다만, 위에 설명되어 있는 버전의 튜플은 C# 7.0 버전 이후부터만 지원되며, 이 글을 쓰는 시점에서 Rhino6의 grasshopper에서는 지원되지 않는것 같다. 아래의 링크에 설명되어 있는 튜플은 사용 가능하다.

https://docs.microsoft.com/ko-kr/dotnet/api/system.tuple?view=net-5.0

 

Tuple 클래스 (System)

튜플 개체를 작성하는 정적 메서드를 제공합니다.Provides static methods for creating tuple objects.

docs.microsoft.com

바로 코드를 보면서 이해해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List<Tuple<stringint>> students = new List<Tuple<stringint>>
{
    new Tuple<stringint>("Alice"99),
    new Tuple<stringint>("Betty"13),
    new Tuple<stringint>("Charlie"66),
    new Tuple<stringint>("David"82),
    new Tuple<stringint>("Emily"3),
};
 
List<string> examAgainList = new List<string>();
 
for (int i = 0; i < students.Count; i++)
{
    if (students[i].Item2 <= 50)
        examAgainList.Add(students[i].Item1);
}
cs

 

students라는 변수는 튜플을 들고있는 리스트다. string을 들고 있는 리스트나 int를 들고 있는 리스트처럼, 튜플을 들고 있는 리스트라고 바로 이해하면 된다. 그리고 리스트에 넣을 튜플은 Tuple<string, int>이라고 되어있는데, 이는 문자열과 정수 값이 순서대로 오는 튜플이라는 뜻이다. 다른 타입을 넣고 싶으면 다른 타입을 넣어도 괜찮고, 뒤에 다른 타입들을 더 이어서 붙이고 싶으면 그것도 가능하다. 예를 들어, Tuple<string, int, int, int, bool> 같은 것도 가능하다. 이 예시에서는 '이름, 점수' 쌍을 저장해두고 싶으므로, string, int 순서로 두었다.

그 다음, list에 값을 넣고 초기화 하는 방법을 그대로 사용하여 List<Tuple<...>> 변수 값을 채워넣었다. 이때 Tuple로 되어있는 리스트를 채워넣어야 하므로 각 값은 Tuple이어야 하며, 그래서 new Tuple<..>(...)과 같은 구문으로 새 튜플을 생성해주었다.

이후에는 재시험을 보아야 하는 이름 리스트를 examAgainList라는 이름으로 만들어 두었고, for문에서는 students에 들어있는 각 아이템을 돌면서 점수가 50점 이하인지 판단하여 이름 값을 examAgainList에 넣어주었다. 여기서 students[i].Item1, students[i].Item2라고 되어있는 것을 보자. Tuple형식으로 되어있는 변수에는 튜플이 들고 있는 아이템 개수에 따라서 Item1, Item2, ... 같은 속성이 들어있고, 이는 튜플에 정의한 순서 그대로다. 여기서는 첫 번째 아이템이 0번이 아니라 1번이다. 그래서 위의 코드에서는 Item2 속성으로 점수를 받아와서 if문 판별을 진행하고, Item1 속성으로 이름을 받아와서 재시험 리스트에 추가해주었다.

 

Comments