[C#] 자료 구조 – List

[C#] 자료 구조 – List

개요

이번 글에서는 C#에서 List를 사용하는 방법에 대해 알아보겠습니다. 리스트는 C#에서 제네릭 컬렉션(General Collection) 중 하나로, 이름 그대로 목록을 의미하며 목록을 검색, 정렬 및 조작하는 메서드를 제공합니다. T에는 모든 타입의 자료형을 넣을 수 있고, 해당 타입의 배열과 비슷한 기능을 가지나 배열과 다르게 가변적으로 사용 할 수 있습니다.

이때까지 대부분 봐왔던 함수와 비슷하게 List도 사용법이 간단 합니다. 바로 예제 알아보도록 하겠습니다.

선언

List<T> 컬렉션 클래스를 선언하는 방법은 간단합니다.

List<T> list = new List<T>();

위에서 설명한대로 T는 어떤 자료형이든 들어갈 수 있습니다. 코드에 T를 그대로 사용할 순 없으니 아래와 같은 사람 클래스(CPerson)을 만들어서 List를 생성해줍니다.

class CPerson
{
    string m_strName; // 이름
    public string NAME
    {
        get
        {
            return m_strName;
        }
    }

    int m_iAge; // 나이
    public int AGE
    {
        get
        {
            return m_iAge;
        }
    }

    public CPerson(string strName, int iAge)
    {
        m_strName = strName;
        m_iAge = iAge;
    }

    public override string ToString()
    {
        return $"name: {NAME}, age: {AGE}";
    }
}

List<CPerson> listPerson = new List<CPerson>(); // List 생성

요소 추가

이렇게 생성한 리스트에 요소를 추가하려면 Add 또는 AddRange 함수를 사용하면 됩니다. Add는 단일 요소를, AddRange를 배열로 이루어진 요소를 추가하는 방식입니다.

// 요소 추가
listPerson.Add(new CPerson("김철수", 10));
listPerson.Add(new CPerson("박민수", 15));
listPerson.Add(new CPerson("이아영", 12));
listPerson.Add(new CPerson("홍길동", 14));

CPerson[] people = { new CPerson("최민수", 20), new CPerson("손흥민", 30), new CPerson("양은호", 10) };
listPerson.AddRange(people);

요소 조회

List에 입력된 요소를 조회 하는 방식은 foreach를 사용하면 쉽게 가능합니다.

foreach (CPerson person in listPerson)
{
    Console.WriteLine(person.ToString());
}

그와 비슷하게 List에는 ForEach 함수도 제공합니다.

listPerson.ForEach(person =>
{
    Console.WriteLine(person.ToString());
});

두 함수 모두 실행하면 리스트 안의 모든 요소의 ToString 함수가 호출되어 문자열이 출력 되는 것을 볼 수 있습니다.

총 개수

요소의 총 개수를 알기 위해서는 Count 함수를 사용합니다.

int iCount = listPerson.Count();
Console.WriteLine($"총 개수: {iCount}");

실행 하면 총 개수를 출력합니다.

특정 조건 요소 인덱스 찾기

특정 조건의 요소의 인덱스를 찾으려면 FindIndex 함수를 사용하면 됩니다.

int iIndex = listPerson.FindIndex(element => element.NAME == "이아영");
Console.WriteLine($"Find Index: {iIndex}");

이름이 “이아영”인 요소의 인덱스가 출력 됩니다.

인덱스로 요소 가져오기

인덱스로 요소를 가져오는 방법은 리스트에 대괄호[]를 사용하여 가져오거나 ElementAt 함수를 사용하여 요소를 가져올 수 있습니다.

try
{
    CPerson cFind = listPerson[iIndex];
    //CPerson cFind = listPerson[10]; // 인덱스 범위 밖이면 ArgumentOutOfRangeException 발생
    Console.WriteLine($"Index: {iIndex}, Find: [{cFind.ToString()}]");
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine(ex.Message);
}
try
{
    CPerson cFind = listPerson.ElementAt(iIndex);
    //CPerson cfind = listPerson.ElementAt(10); // 인덱스 범위 밖이면 ArgumentOutOfRangeException 발생
    Console.WriteLine($"Index: {iIndex}, Find: [{cFind.ToString()}]");
    element = cFind;
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine(ex.Message);
}

두 함수 모두 인덱스 값이 범위 내의 값이 아니면 ArgumentOutOfRangeException을 발생 시킵니다. 그래서 Count로 입력 범위를 체크해주거나, 혹은 위와 같이 try catch문을 사용해야 합니다.

요소로 인덱스 가져오기

요소로 인덱스를 가져오는 방법은 IndexOf 함수를 사용하면 됩니다.

int iIndexByElement = listPerson.IndexOf(element);
Console.WriteLine($"elementment: [{element.ToString()}], index: {iIndexByElement}");

요소 존재 유무 확인

요소가 존재하는 유무를 판단하는 함수는 Contains 함수를 사용하면 됩니다.

bool bContain = listPerson.Contains(element);
Console.WriteLine($"is contain : {bContain}");

정렬하기

정렬할 때는 Sort 함수를 사용하면 됩니다. 다만 이번 예제에서는 T가 CPerson이므로 Sort 함수 인자로 람다식을 입력하면 됩니다.

listPerson.Sort((x, y) => x.NAME.CompareTo(y.NAME)); // 이름 기준 정렬
foreach (CPerson person in listPerson)
{
    Console.WriteLine(person.ToString());
}

listPerson.Sort((x, y) => x.AGE.CompareTo(y.AGE)); // 나이 기준 정렬
foreach (CPerson person in listPerson)
{
    Console.WriteLine(person.ToString());
}

삭제

리스트에 요소를 삭제할 땐 Remove, RemoveAt 함수, 모든 요소를 삭제할 땐 Clear 함수를 사용하면 됩니다.

// 요소로 삭제
listPerson.Remove(element);

// 인덱스로 삭제
listPerson.RemoveAt(0);

// 모든 요소 삭제
listPerson.Clear();

github : https://github.com/3001ssw/c_sharp/tree/main/Data_Struct/List