2009-05-31 6 views
32

C#의 SortedDictionary를 통해 역순으로 역순으로 반복 할 수있는 방법이 있습니까?.NET에서 역 정렬 된 사전

또는 내림차순으로 SortedDictionary를 정의하는 방법이 있습니까?

+0

당신은 말을하지 않습니까? –

+0

네, 그렇게 생각합니다 ;-) – Dario

+3

Typo ... 모든 인간 컴파일러에 감사드립니다. :-) –

답변

59

SortedDictionary 자체는 역방향 반복을 지원하지 않지만 동일한 효과를 얻을 수있는 여러 가지 방법이 있습니다.

  1. .Reverse -Method (Linq)를 사용하십시오.

    var Rand = new Random(); 
    
    var Dict = new SortedDictionary<int, string>(); 
    
    for (int i = 1; i <= 10; ++i) { 
        var newItem = Rand.Next(1, 100); 
        Dict.Add(newItem, (newItem * newItem).ToString()); 
    } 
    
    foreach (var x in Dict.Reverse()) { 
        Console.WriteLine("{0} -> {1}", x.Key, x.Value); 
    } 
    
  2. 가 내림차순으로 사전 종류를 확인합니다 (이 전체 사전 출력을 미리 계산해야하지만 가장 간단한 솔루션입니다).

    class DescendingComparer<T> : IComparer<T> where T : IComparable<T> { 
        public int Compare(T x, T y) { 
         return y.CompareTo(x); 
        } 
    } 
    
    // ... 
    
    var Dict = new SortedDictionary<int, string>(new DescendingComparer<int>()); 
    
  3. 사용 SortedList<TKey, TValue> 대신. 성능은 사전 (O (logn) 대신 O (n))만큼 좋지는 않지만 배열과 같은 요소에서 임의 액세스가 가능합니다. 제네릭 IDictionary-Interface를 사용하면 나머지 코드를 변경할 필요가 없습니다. SortedLists

편집 :: 순회 그냥 인덱스로 요소에 액세스!

var Rand = new Random(); 


var Dict = new SortedList<int, string>(); 

for (int i = 1; i <= 10; ++i) { 
    var newItem = Rand.Next(1, 100); 
    Dict.Add(newItem, (newItem * newItem).ToString()); 
} 

// Reverse for loop (forr + tab) 
for (int i = Dict.Count - 1; i >= 0; --i) { 
    Console.WriteLine("{0} -> {1}", Dict.Keys[i], Dict.Values[i]); 
} 
+0

고마워, 정말 도움이 됐어! –

14

시작하는 역순 SortedDictionary을 정의하는 가장 쉬운 방법은 정상 역순 정렬 IComparer<TKey>로를 제공하는 것이다.

using System.Collections.Generic; 

namespace MiscUtil.Collections 
{ 
    /// <summary> 
    /// Implementation of IComparer{T} based on another one; 
    /// this simply reverses the original comparison. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public sealed class ReverseComparer<T> : IComparer<T> 
    { 
     readonly IComparer<T> originalComparer; 

     /// <summary> 
     /// Returns the original comparer; this can be useful 
     /// to avoid multiple reversals. 
     /// </summary> 
     public IComparer<T> OriginalComparer 
     { 
      get { return originalComparer; } 
     } 

     /// <summary> 
     /// Creates a new reversing comparer. 
     /// </summary> 
     /// <param name="original">The original comparer to 
     /// use for comparisons.</param> 
     public ReverseComparer(IComparer<T> original) 
     { 
      if (original == null) 
      { 
       throw new ArgumentNullException("original"); 
      } 
      this.originalComparer = original; 
     } 

     /// <summary> 
     /// Returns the result of comparing the specified 
     /// values using the original 
     /// comparer, but reversing the order of comparison. 
     /// </summary> 
     public int Compare(T x, T y) 
     { 
      return originalComparer.Compare(y, x); 
     } 
    } 
} 

당신은 다음 사용하십시오 :

var dict = new SortedDictionary<string, int> 
    (new ReverseComparer<string>(StringComparer.InvariantCulture)); 

(또는 어떤 종류 사용했다)

여기 당신을 위해 쉽게 것을 확인 할 수 MiscUtil에서 일부 코드입니다.

한 방향으로 만 반복하려는 경우 나중에 순서를 바꾸는 것보다 더 효율적입니다.

+1

델리게이트가 다루기가 훨씬 쉽기 때문에 (람다 메서드) 012-에서 Comparer 까지 프레임 워크 통합 캐스팅 메서드를 제공하는 것이 매우 유용 할 것입니다 .-) – Dario

+1

MiscUtil 클래스도 있습니다. :) –

+0

좋은 ;-) 어쨌든 프레임 워크의 일부 여야합니다. 내부적으로 그런 클래스도 있지만 개인적으로 개최됩니다 :-) – Dario

-1

당신이 .NET 3.5을 사용하는 경우, 당신은 OrderByDescending 확장 방법을 사용할 수 있습니다 : 당신은 단순히 부정하는 것입니다 키와 숫자 값을 처리하는 경우 매우 간단한 방법도

 var dictionary = new SortedDictionary<int, string>(); 
     dictionary.Add(1, "One"); 
     dictionary.Add(3, "Three"); 
     dictionary.Add(2, "Two"); 
     dictionary.Add(4, "Four"); 



     var q = dictionary.OrderByDescending(kvp => kvp.Key); 
     foreach (var item in q) 
     { 
      Console.WriteLine(item.Key + " , " + item.Value); 
     } 
+0

그건 나빠! OrderByDescending은 이미 정렬 된 데이터를 정렬하기 위해 O (nlogn) 시간이 필요합니다! – Dario

+0

좋은 지적으로, 나는 Linq를 모든 것에 익숙해 져야한다. – BFree

2

이를 당신이 사전을 만들 때 그것들.

0

간략히 역순 정렬 사전 을 한 줄에 만듭니다..

var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x))); 

System.Collections.Generic.Comparer<T>를 사용하여 IComparer<T>을 만드는 방법이있다. Create 메서드에 IComparision<T> 대리자를 전달하여 IComparer<T>을 작성하면됩니다.

var dict = new SortedDictionary<int, TValue>(
    Comparer<int>.Create(
     delegate(int x, int y) 
     { 
      return y.CompareTo(x); 
     } 
    ) 
); 

당신은 그들의 중요성 (TKey, TKey) => int을 경우 대리인을 대체 할 람다 식을/지역 기능/방법를 사용할 수 있습니다.