본문 바로가기
개발/Unity

유니티 C# - 비교 함수를 이용하여 리스트 정렬하기 (List Sorting with Compare)

by 피로물든딸기 2022. 11. 22.
반응형

Unity 전체 링크

 

먼저 List를 출력하는 함수를 만들자.

    void printList<T>(List<T> list)
    {
        string text = string.Empty;
        foreach (T l in list) text += l.ToString() + ", ";
        Debug.Log(text);
    }

 

기본적으로 int 타입의 List에서 Sort()를 실행하면 오름차순 정렬이 된다.

    List<int> listInt = new List<int>();
        
    listInt.Add(5);
    listInt.Add(7);
    listInt.Add(3);
    listInt.Add(7);
    listInt.Add(-2);
    listInt.Add(-4);

    listInt.Sort();
        
    printList(listInt);

 

실행결과는 아래와 같다.

 

하지만 만약에 벡터를 정렬한다고 가정해보자.

    List<Vector3> listVector = new List<Vector3>();

    listVector.Add(new Vector3(5, 0, 0));
    listVector.Add(new Vector3(2, 0, 0));
    listVector.Add(new Vector3(3, 0, 0));
    listVector.Add(new Vector3(2, 0, 0));
    listVector.Add(new Vector3(4, 0, 0));
    listVector.Add(new Vector3(1, 0, 0));

    listVector.Sort();
    printList(listVector);

 

아래와 같이 ArgumentException 에러가 발생한다.

 

벡터를 정렬할 기준이 없기 때문이다.

따라서 벡터의 크기를 비교하여 정렬할 수 있도록 크기를 비교 함수를 만들자.

-1이 return되는 값이 앞으로 정렬된다.

    int compare1(Vector3 a, Vector3 b)
    {
        return a.magnitude < b.magnitude ? -1 : 1;
    }

 

이 compare1을 Sort에 인자로 넘겨주면 된다.

listVector.Sort(compare1);

 

실행결과는 다음과 같다.

Vector의 크기가 작은 순으로 정렬된 것을 알 수 있다.


만약 특정 점에 가까운 순으로 정렬해야한다면 어떻게 해야할까?

이 경우에는 아래와 같이 비교 함수를 만들 수 있다.

즉, 점 c에 가까울수록 먼저 정렬된다.

    int compare2(Vector3 a, Vector3 b, Vector3 c)
    {
        float lengthAC = Vector3.Distance(a, c);
        float lengthBC = Vector3.Distance(b, c);

        return lengthAC < lengthBC ? -1 : 1;
    }

 

하지만 compare2는 추가된 parameter인 Vector3 c 때문에 인자로 넘겨줄 수 없다.

 

이 경우는 아래와 같이 delegate를 이용하여 Sort 내에 compare를 구현한다.

    listVector.Sort(delegate (Vector3 a, Vector3 b)
    {
        return compare2(a, b, new Vector3(3.7f, 0, 0));
    });

    printList(listVector);

 

게임을 실행하면 3.7f와 가까운 순서인 4, 3, 5, 2, 2, 1 로 정렬된다.

 

전체 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ListSort : MonoBehaviour
{
    void printList<T>(List<T> list)
    {
        string text = string.Empty;
        foreach (T l in list) text += l.ToString() + ", ";
        Debug.Log(text);
    }

    int compare1(Vector3 a, Vector3 b)
    {
        return a.magnitude < b.magnitude ? -1 : 1;
    }

    int compare2(Vector3 a, Vector3 b, Vector3 c)
    {
        float lengthAC = Vector3.Distance(a, c);
        float lengthBC = Vector3.Distance(b, c);

        return lengthAC < lengthBC ? -1 : 1;
    }

    void Start()
    {
        List<int> listInt = new List<int>();
        
        listInt.Add(5);
        listInt.Add(7);
        listInt.Add(3);
        listInt.Add(7);
        listInt.Add(-2);
        listInt.Add(-4);

        listInt.Sort();
        
        printList(listInt);

        List<Vector3> listVector = new List<Vector3>();

        listVector.Add(new Vector3(5, 0, 0));
        listVector.Add(new Vector3(2, 0, 0));
        listVector.Add(new Vector3(3, 0, 0));
        listVector.Add(new Vector3(2, 0, 0));
        listVector.Add(new Vector3(4, 0, 0));
        listVector.Add(new Vector3(1, 0, 0));

        listVector.Sort(compare1);
        printList(listVector);

        listVector.Sort(delegate (Vector3 a, Vector3 b)
        {
            return compare2(a, b, new Vector3(3.7f, 0, 0));
        });

        printList(listVector);
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글