2009-07-04 3 views
1

누구든지 도움을받을 수 있습니다. 정렬 작업을 수행하는 데 문제가 있습니다. 정렬되었지만 작동하지 않는 것으로 보입니다.List (sort)에 대한 사용자 지정 IComparer 문제 - C#

나는 다음과 같은 값

8,6,10,11,7를 저장하는 목록이

나는 또한 다른 목록을

(내 클래스의 액세서리는 accessoryId 전류 클래스라는 PROPERT있다 이드의 순서는 현재 6,7,8,10,11)

따라서 나는 그들을 6,7,8,10,11에서 간단한 목록에서 사용한 순서대로 정렬해야한다. , 6,10,11,7

나는 내 icomparable (아래 참조)이 있는데, 목록이 아직 내 모든 클래스가 있지만, 비교 자가 정확한지 6,7,8,10,11

// accesories is the IList<Accessories> (hence why i am use ToList) 
    // and sortOrder is the simple int list list<int> 
    accesories.ToList().Sort(new ItemTpComparer(sortOrder)); 

class ItemTpComparer : IComparer<Accessories> 
{ 
    private IList<int> otherList; 

    public ItemTpComparer(IList<int> otherList) 
    { 
     this.otherList = otherList; 
    } 

    #region IComparer<Accessories> Members 

    public int Compare(Accessories x, Accessories y) 
    { 

     if (otherList.IndexOf(x.AccessoryId) > otherList.IndexOf(y.AccessoryId)) 
      return 1; 

     else if (otherList.IndexOf(x.AccessoryId) < otherList.IndexOf(y.AccessoryId)) 
      return -1; 
     else 
      return 0; 

     // tried below also didn't work 
     //return otherList.IndexOf(x.AccessoryId) - otherList.IndexOf(y.AccessoryId); 

답변

9

의 순서로 여전히 (심지어 주석 한 줄 버전)이기 때문 입력 않지만 뭔가 잘못이다 . 문제는 ToList()IEnumerable<T> 개체의 복사본을 포함하는 새 List을 기본적으로 생성하므로 새 목록을 만들고 정렬하여 버립니다.

var sortedList = accesories.ToList(); 
sortedList.Sort(new ItemTpComparer(sortOrder)); 

있는 난으로 대체하는 게 좋을 것 :

var sortedList = accessories.OrderBy(sortOrder.IndexOf).ToList(); 

이런 식으로, 어떤 비교 자 구현이 필요하지 않을 것입니다. 당신은 또한 일종의 쉽게 내림차순 수 : 객체가 정말 List<Accessories> 경우

var sortedList = accessories.OrderByDescending(sortOrder.IndexOf).ToList(); 

, 당신은 또한 장소에 정렬 할 수 있습니다 :

((List<Accessories>)accessories).Sort(new ItemTpComparer(sortOrder)); 
+0

와우! 정말 감사합니다. .. "var sortedList = accesories.OrderBy (item => sortOrder.IndexOf (item.AccessoryId)) .ToList();" 또한 정렬 수가 적은 경우 (예 : 8,6 ..을 제공하고 정렬하는 경우) ... 훌륭합니다. 결과는 8,6이 결과 끝에 정렬됩니다. 가능합니까? 처음부터 8,6을 정렬하고 더 이상 일행이 없기 때문에 결국에는 나머지를 순서대로 정렬합니까? –

+0

@mark smith : 존재하지 않는 항목에 대해서는'IndexOf'가 -1을 반환하기 때문입니다. 내림차순 정렬에 대한 대답을 업데이트하고 있습니다. –

+0

큰 감사 ... 고정! –

1

메흐 다드 당신을 보여리스트가 정렬되지 않은 이유. 나는 비교 자의 성능을 언급하고 정렬 된 항목보다 적은 정렬 항목으로 문제를 해결하려고합니다.

목록에서 IndexOf를 사용하면 색인을 찾는 데 상당히 비효율적입니다. 목록에있는 항목을 반복하여 올바른 항목을 찾아야합니다.

class ItemTpComparer : IComparer<Accessories> { 

    private Dictionary<int, int> index; 

    public ItemTpComparer(IList<int> otherList) { 
     index = new Dictionary<int, int>(); 
     for (int i = 0; i < otherList.Count; i++) { 
     index.Add(otherList[i], i); 
     } 
    } 

    public int Compare(Accessories x, Accessories y) { 
     return index[x.AccessoryId].CompareTo(index[y.AccessoryId]); 
    } 

} 

당신은 정렬 할 항목의 목록보다 짧은 것으로 정렬 기준으로 값 목록을 허용 할 경우, 당신이 있는지 확인 : 한 번 항목을 통해 당신은 단지 루프 대신 그 방법을 찾아보기로 사전을 사용 그 값은 사전에 있습니다 :

public int Compare(Accessories x, Accessories y) { 
     int xIndex, yIndex; 
     if (!index.TryGetValue(x.AccessoryId, out xIndex)) xIndex = int.MaxValue; 
     if (!index.TryGetValue(y.AccessoryId, out yIndex)) yIndex = int.MaxValue; 
     return xIndex.CompareTo(yIndex); 
    } 
+0

고맙습니다 ... 많은 메모를 찍은 .. 그것은 편리하게 올지 모르지만 현재 나는 또한 그것을 배울 필요가 람다 물건을 사용하고 있습니다 :-). 하지만 고맙습니다. –

+0

람다 솔루션은 인덱스 사전을 생성하고 IndexOf 대신에 사용하지 않는 한 동일한 성능 문제가 있습니다. – Guffa