>

두 가지 다른 기준으로 정렬하려면 어떻게해야합니까?

예를 들어, 다음과 같은 person 객체가 있습니다 :

Person  속성 FirstName  (문자열), LastNameRank  (int).

예제 데이터 :

Xavier    Smith 1
Alexander Smith 2
Alexander Smith 1
Bob       Hawke 2

이름순으로 알파벳순으로 정렬 한 다음 순위별로 정렬해야합니다 (예 : 결과 :

Alexander Smith 1
Alexander Smith 2
Bob       Hawke 2
Xavier    Smith 1

지금까지 다음을 시도했지만 제대로 작동하지 않습니다.

peopleList   List<Person> 입니다

peopleList.Sort(new Comparison<Person>((x,y) => x.Rank.CompareTo(y.Rank)));
peopleList.Sort(new Comparison<Person>((x, y) => string.Compare(x.Name, y.Name)));

감사합니다

수정 :코드를 너무 많이 변경하지 않으려면 위의 행을 다음과 같이 변경하면 목록을 유지하고 싶습니다.

peopleList.OrderBy(person => person.FirstName).ThenBy(person => person.Rank).ToList();

정확하게 정렬 된 것과 정확히 동일한 목록을 제공 하시겠습니까?

  • 답변 # 1

    LINQ 접근법

    LINQ를 사용하면 OrderBy 및 ThenBy를 사용할 수 있습니다 :

    var result = peopleList.OrderBy(p => p.FirstName).ThenBy(p => p.Rank);
    
    

    이것은 IEnumerable<T> 를 반환합니다 . 정말 List<T> 가 필요한 경우   .ToList() 를 추가  마지막에.

    Sort 를 사용하려면  메소드를 사용하면 맞춤 비교기를 작성해야합니다.

    편집 : ToList() 사용  새 목록을 반환합니다. 기존 목록을 정렬하려면 Sort 를 사용해야합니다  목록을 반환하지 않고 현재 목록에서 작동하는 메소드 ( void 입니다)  방법).

    정렬/비교기 접근

    용도 : list.Sort(new PersonComparer());

    비교 코드는 다음과 같습니다. MSDN 예제에서 수정되었으므로 이러한 방식으로 구성되는 이유를 이해하는 데 사용 된 주석을 읽는 것이 좋습니다.

    public class PersonComparer : IComparer<Person>
    {
        public int Compare(Person x, Person y)
        {
            if (x == null)
            {
                if (y == null)
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                if (y == null)
                {
                    return 1;
                }
                else
                {
                    int retval = x.FirstName.CompareTo(y.FirstName);
                    if (retval != 0)
                    {
                        return retval;
                    }
                    else
                    {
                        return x.Rank.CompareTo(y.Rank);
                    }
                }
            }
        }
    }
    
    

  • 답변 # 2

    다른 답변은 이것보다 더 우아해 보이고 멍청한듯한 느낌이 들지만, 이런 정렬 방법을 이해하면 어떤 방식 으로든 어떤 종류의 목록이든 정렬 할 수 있습니다 많은 것을 알고 있습니다. 완전히 새로운 클래스를 작성할 필요는 없습니다 (비교 클래스를 작성하면 코드의 다른 부분에서 다른 유사한 목록을 정렬하는 경우 유용 할 수 있습니다).

    peopleList.Sort((x, y) =>
        {
            int compare = x.FirstName.CompareTo(y.FirstName);
            if (compare != 0)
                return compare;
            compare = x.Rank.CompareTo(y.Rank);
            if (compare != 0)
                return compare;
            return x.LastName.CompareTo(y.LastName);
        });
    
    

  • 답변 # 3

    LINQ 답변이 마음에 듭니다. 옵션이 아닌 경우 언제든지 사용할 수 있습니다

    (x,y) => 2*string.Compare(x.Name,y.Name) + x.Rank.CompareTo(y.Rank)
    
    

    문자열 비교는 항상 0이 아닌 한 항상 지배합니다

  • 답변 # 4

    실제로 정렬 람다 구문에 가깝습니다. 람다는 자체 범위로 묶을 수 있다는 사실을 놓쳤습니다.

    peopleList.Sort(new Comparison<Person>((x,y) =>
    {
        int result = x.FirstName.CompareTo(y.FirstName);
        return (result != 0) ? result : x.Rank.CompareTo(y.Rank);
    }));
    
    

    자신 만의 IComparer<Person> 를 쓰는 것보다 조금 덜 노력합니다 !

  • 이전 macos - NSAttributedString size () 메서드가 잘못된 너비를 반환합니다
  • 다음 java - KG, Litre, Metre, KM 등과 같은 다양한 항목 단위를 나타내는 API가 있습니까?