상세 컨텐츠

본문 제목

[Unity] 유니티 배열 리스트 등등 정렬 관련

게임엔진관련/유니티 엔진

by AlrepondTech 2020. 1. 14. 14:20

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

출처: https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.generic.list-1.sort?view=netframework-4.8

List<T>.Sort 메서드

정의

네임스페이스:System.Collections.Generic어셈블리:System.Collections.dll, mscorlib.dll, netstandard.dll

지정된 또는 기본 List<T> 구현 또는 제공된 IComparer<T> 대리자를 사용하여 Comparison<T>의 요소 또는 요소의 일부를 정렬하여 목록 요소를 비교합니다.

오버로드

Sort(Comparison<T>) 지정된 List<T>을 사용하여 전체 Comparison<T>의 요소를 정렬합니다.
Sort(Int32, Int32, IComparer<T>) 지정된 비교자를 사용하여 List<T>의 요소 범위에 있는 요소를 정렬합니다.
Sort() 기본 비교자를 사용하여 전체 List<T>의 요소를 정렬합니다.
Sort(IComparer<T>) 지정된 비교자를 사용하여 전체 List<T>에 있는 요소를 정렬합니다.

Sort(Comparison<T>)

지정된 List<T>을 사용하여 전체 Comparison<T>의 요소를 정렬합니다.

C#복사

 

public void Sort (Comparison<T> comparison);매개 변수

comparisonComparison<T>

요소를 비교할 때 사용할 Comparison<T>입니다.

예외

ArgumentNullException

comparison가 null인 경우

ArgumentException

comparison의 구현으로 인해 정렬 중에 오류가 발생했습니다. 예를 들어 항목을 자기 자신과 비교할 때 comparison에서 0을 반환하지 않을 수 있습니다.

예제

다음 코드에서는 간단한 비즈니스 개체에 대 한 Sort  Sort 메서드 오버 로드를 보여 줍니다. Sort 메서드를 호출 하면 파트 형식에 대해 기본 비교 자가 사용 되며, Sort 메서드는 무명 메서드를 사용 하 여 구현 됩니다.

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify the type of part 
// but the part name can change. 
public class Part : IEquatable , IComparable
{
    public string PartName { get; set; }

    public int PartId { get; set; }

    public override string ToString()
    {
        return "ID: " + PartId + "   Name: " + PartName;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Part objAsPart = obj as Part;
        if (objAsPart == null) return false;
        else return Equals(objAsPart);
    }
    public int SortByNameAscending(string name1, string name2)
    {
        
        return name1.CompareTo(name2);
    }

    // Default comparer for Part type.
    public int CompareTo(Part comparePart)
    {
          // A null value means that this object is greater.
        if (comparePart == null)
            return 1;
            
        else
            return this.PartId.CompareTo(comparePart.PartId);
    }
    public override int GetHashCode()
    {
        return PartId;
    }
    public bool Equals(Part other)
    {
        if (other == null) return false;
        return (this.PartId.Equals(other.PartId));
    }
    // Should also override == and != operators.

}
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        List parts = new List();

        // Add parts to the list.
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName= "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 }); ;
        // Name intentionally left null.
        parts.Add(new Part() {  PartId = 1334 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });

        // Write out the parts in the list. This will call the overridden 
        // ToString method in the Part class.
        Console.WriteLine("\nBefore sort:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        // Call Sort on the list. This will use the 
        // default comparer, which is the Compare method 
        // implemented on Part.
        parts.Sort();

        Console.WriteLine("\nAfter sort by part number:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
       
        // This shows calling the Sort(Comparison(T) overload using 
        // an anonymous method for the Comparison delegate. 
        // This method treats null as the lesser of two values.
        parts.Sort(delegate(Part x, Part y)
        {
            if (x.PartName == null && y.PartName == null) return 0;
            else if (x.PartName == null) return -1;
            else if (y.PartName == null) return 1;
            else return x.PartName.CompareTo(y.PartName);
        });

        Console.WriteLine("\nAfter sort by name:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
       
        /*
       
            Before sort:
        ID: 1434   Name: regular seat
        ID: 1234   Name: crank arm
        ID: 1634   Name: shift lever
        ID: 1334   Name:
        ID: 1444   Name: banana seat
        ID: 1534   Name: cassette

        After sort by part number:
        ID: 1234   Name: crank arm
        ID: 1334   Name:
        ID: 1434   Name: regular seat
        ID: 1444   Name: banana seat
        ID: 1534   Name: cassette
        ID: 1634   Name: shift lever

        After sort by name:
        ID: 1334   Name:
        ID: 1444   Name: banana seat
        ID: 1534   Name: cassette
        ID: 1234   Name: crank arm
        ID: 1434   Name: regular seat
        ID: 1634   Name: shift lever

         */

    }
}

 

 

다음 예제에서는 Sort(Comparison<T>) 메서드 오버 로드를 보여 줍니다.

이 예에서는 CompareDinosByLength명명 된 문자열에 대 한 대체 비교 방법을 정의 합니다. 이 메서드는 다음과 같이 작동 합니다. 첫째, 비교는 null에 대해 테스트 되 고 null 참조는 null이 아닌 값으로 처리 됩니다. 둘째, 문자열 길이 비교 하 고 더 긴 문자열인 큰 것으로 간주 됩니다. 셋째, 길이가 같으면 일반적인 문자열 비교가 됩니다.

문자열의 List<T> 생성 되어 특정 순서로 4 개의 문자열로 채워집니다. 목록에는 빈 문자열 및 null 참조도 포함 됩니다. 이 목록은 CompareDinosByLength 메서드를 나타내는 Comparison<T> 제네릭 대리자를 사용 하 여 정렬 되 고 다시 표시 됩니다.

 

using System;
using System.Collections.Generic;

public class Example
{
    private static int CompareDinosByLength(string x, string y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }
            else
            {
                // If x is null and y is not null, y
                // is greater. 
                return -1;
            }
        }
        else
        {
            // If x is not null...
            //
            if (y == null)
                // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {
                // ...and y is not null, compare the 
                // lengths of the two strings.
                //
                int retval = x.Length.CompareTo(y.Length);

                if (retval != 0)
                {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    //
                    return retval;
                }
                else
                {
                    // If the strings are of equal length,
                    // sort them with ordinary string comparison.
                    //
                    return x.CompareTo(y);
                }
            }
        }
    }

    public static void Main()
    {
        List dinosaurs = new List();
        dinosaurs.Add("Pachycephalosaurus");
        dinosaurs.Add("Amargasaurus");
        dinosaurs.Add("");
        dinosaurs.Add(null);
        dinosaurs.Add("Mamenchisaurus");
        dinosaurs.Add("Deinonychus");
        Display(dinosaurs);

        Console.WriteLine("\nSort with generic Comparison delegate:");
        dinosaurs.Sort(CompareDinosByLength);
        Display(dinosaurs);

    }

    private static void Display(List list)
    {
        Console.WriteLine();
        foreach( string s in list )
        {
            if (s == null)
                Console.WriteLine("(null)");
            else
                Console.WriteLine("\"{0}\"", s);
        }
    }
}

/* This code example produces the following output:

"Pachycephalosaurus"
"Amargasaurus"
""
(null)
"Mamenchisaurus"
"Deinonychus"

Sort with generic Comparison delegate:

(null)
""
"Deinonychus"
"Amargasaurus"
"Mamenchisaurus"
"Pachycephalosaurus"
 */

 

설명

comparison 제공 되는 경우 List<T>의 요소는 대리자가 나타내는 메서드를 사용 하 여 정렬 됩니다.

comparison null되 면 ArgumentNullException이 throw 됩니다.

이 메서드는 다음과 같이 내면적인 sort를 적용 하는 Array.Sort을 사용 합니다.

  • 파티션 크기가 16 개의 요소 보다 작거나 같으면 삽입 정렬 알고리즘을 사용 합니다.
  • 파티션 수가 2 개 로그 n을 초과 하는 경우 n 은 입력 배열의 범위이 고 heapsort 알고리즘을 사용 합니다.
  • 그렇지 않으면 빠른 정렬 알고리즘을 사용합니다.

이 구현은 수행 불안정 한 정렬을; 즉, 두 요소가 같은 경우 순서 유지 되지 않을 수 있습니다. 반면, 안정 된 정렬 같지 않은 요소의 순서를 유지 합니다.

평균적으로이 메서드는 O (n log n) 작업입니다. 여기서 n  Count입니다. 최악의 경우에는 O (n2) 작업입니다.

 

 

 

 

반응형

 

728x90

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: https://bravochoi.tistory.com/134

 

어떤 형식을 List로 만들어서 관리할때 sort를 해야 할 경우도 생깁니다. (당연..;;;)

List의 Sort는 기본적으로 4개의 오버로드가 존재합니다.
1. List.Sort()
2. List.Sort(제네릭 Comparison)
3. List.Sort(제네릭 IComparer)
4. List.Sort(Int32, Int32, 제네릭 IComparer)

아무런 파라미터를 받지 않는 기본 Sort도 있고
특정 파라미터를 받는 Sort도 있는데
그 사용법을 간단히 정리해 보면

일단 리스트가 있어야 하니..
List myList = new List(); myList.Add("Daum"); myList.Add("Google"); myList.Add("Bing"); myList.Add("Naver");

이런 리스트가 있다고 할때
2번의 Sort를 쓰려면

public int compare(string x, string y)
{
return x.CompareTo(y);
}
요런 메서드를 하나 만들어서 (물론 구현내용은 자유롭겠져. 반환값만 -1,0,1 이면 뭐)

myList.Sort(compare);
이렇게 써주면 됩니다.

3번 Sort를 쓰려면
IComparer 을 구현한 클래스를 만들어야 합니다.

public class StringCompare : IComparer
{
public int Compare(string x, string y)
{
return x.CompareTo(y);
}
}
요런 클래스를 만든 후에

StringCompare sc = new StringCompare();
myList.Sort(sc);
요렇게 쓰면 되져. 
 4번 방법이야 sort할 index를 정해주는거니 별 차이 없구여

근데 sort를 무명메서드를 이용해서 코드를 만들수도 있습니다.
무명메서드는 delegate로 해도 되고 람다식을 써도 됩니다.

delegate를 쓰면
myList.Sort(delegate(string x, string y)
{
return x.CompareTo(y);
});
람다식을 쓰면
myList.Sort((string x, string y) => x.CompareTo(y));
이렇게 쓰면 됩니다.
취향따라 쓰면 되겠네요.

참고로 MSDN을 보면
Sort의 정렬방식에 대해 이렇게 써 있어요

출처: https://bravochoi.tistory.com/134 [즐거운인생]

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: https://m.blog.naver.com/PostView.nhn?blogId=zparkx&logNo=220372363226&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

 

이것은 클래스 구조의 맴버 변수인 d의 값을 조사해서 내림차순으로 정렬하는 코드.

 

5번 라인에서 클래스를 선언 되어있습니다. 

 

맴버 변수로는 d라는 값. 이것은 정렬할때 사용할 것입니다.

 

13번 라인에서 난수를 가지고 있는 Data클래스. 10개를 List에 넣었습니다

 

19번째 라인에서는 흥미진진.

 

Sort라는 함수는 분류를 해주는 것인데 그냥 실행하면 정렬이 됩니다.

하지만 위 상황은 다릅니다! 

맴버 변수가 있는 상황 이라면.. 혹은 맴버변수가 여러개라면.. 무엇을 기준으로 정렬해야 할지 지정해야 합니다.

 

Sort내부에 들어간 delegate라는 것은 무명 메서드라는 표현이 맞을 것 같군요.

독학으로 배운터라 자세한 내용은 기술하진 않지만 'Sort 메서드에서 인자 2개를 받아낸 뒤((Data a, Data b )부분) 그 값을 비교하겠다' 라는 표현.

 

CompateTo는 두 값을 비교하여 크면1, 작으면 -1, 같으면 0을 리턴합니다.

 

이것 말고 람다식으로 표현할 수 있습니다.

list.Sort( (Data a, Data b) => a.d.CompareTo(b.d) );

 

좀 더 관심이 있으신분은 Comparison , Interface , IComparable 로 연구해보시면 좋을 것 같습니다.

유니티로 게임을 만드는 회사는 대부분 람다식을 즐겨 사용하는 편이지만요.. :)

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역