2010-07-27 33 views
7

Cách lấy một số Enumerator vào một mục trong từ điển -Sorted- bằng cách sử dụng khóa?Phím tiếp theo trong C# Dictionary

Lưu ý:GetEnumerator() được một Enumerator đến yếu tố đầu tiên ..

Nhưng tôi cần phải nhận được một Enumerator tới phần tử với một chìa khóa nhất định để đạt được quyền truy cập vào các yếu tố tiếp theo sử dụng MoveNext() ví dụ ...

Edit: Hoặc một cách để truy cập vào các yếu tố tiếp theo ...

Edit: tôi muốn có một phương pháp thời gian const ...

Cảm ơn

Trả lời

7
var enumerator = dictionary.Keys.SkipWhile(k => k != myKey) 

đâu MyKey là chìa khóa bạn đang tìm kiếm. Và bạn có thể sử dụng phương thức mở rộng OrderBy nếu bạn muốn sắp xếp các khóa.

Chỉnh sửa: Bạn không thể làm điều đó liên tục với Dictionary/SortedDictionary. Tại sao không thực hiện cây tìm kiếm nhị phân của riêng bạn (như SortedDictionary là) và bạn sẽ có tra cứu thời gian O (log n) và O (1) thời gian .next()?

1

Bạn không thể làm điều đó với Dictionary. Bạn có thể thực hiện việc có khả năng truy cập theo chỉ mục, vì vậy bạn có thể sử dụng SortedList thay vì từ điển. Ngoài ra, bạn có thể xem SkipWhile.

Mặc dù bạn có thể có một số cách giải quyết như thế này:

Dictionary<int, int> dictionary = new Dictionary<int, int>(); 
foreach (KeyValuePair<int, int> pair in dictionary) 
{ 
    // you can check the key you need and assume that the next one will be what you need. 
} 

Nhưng tất nhiên đây không phải là ý tưởng tốt nhất.

0
var query = yourDictionary.SkipWhile(kvp => kvp.Key != keyToFind); 
foreach (var result in query) 
{ 
    // ... 
} 
1

Nếu bạn có Framework> = 3.5 đã cài đặt sử dụng SkipWhile Janus Tondering và LukeH đề xuất. Đối với các phiên bản khung công tác thấp hơn, bạn phải tự làm điều đó (ví dụ: điền một từ điển thứ hai với các keyvaluepairs từ chìa khóa của bạn đến cuối).

0

Tùy chọn đơn giản nhất là sử dụng SortedList và sau đó thêm phương thức tiện ích mở rộng để trả về số IEnumerable có phần tử lớn hơn hoặc bằng khóa đã cho. Độ phức tạp của phương pháp GetElementsGreaterThanOrEqual dưới đây là O (log (n)) để lấy phần tử đầu tiên và sau đó mỗi lần lặp lại sau đó là O (1).

public static class SortedListExtension 
{ 
    public static IEnumerable<KeyValuePair<TKey, TValue>> GetElementsGreaterThanOrEqual<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey> 
    { 
     int index = instance.BinarySearch(target); 
     if (index < 0) 
     { 
      index = ~index; 
     } 
     for (int i = index; i < instance.Count; i++) 
     { 
      yield return new KeyValuePair<TKey, TValue>(instance.Keys[i], instance.Values[i]); 
     } 
    } 

    public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey> 
    { 
     int lo = 0; 
     int hi = instance.Count - 1; 
     while (lo <= hi) 
     { 
      int index = lo + ((hi - lo) >> 1); 
      int compare = instance.Keys[index].CompareTo(target); 
      if (compare == 0) 
      { 
       return index; 
      } 
      else 
      { 
       if (compare < 0) 
       { 
        lo = index + 1; 
       } 
       else 
       { 
        hi = index - 1; 
       } 
      } 
     } 
     return ~lo; 
    } 
} 
+0

Làm thế nào phương pháp này sẽ được sử dụng/được gọi là? – vapcguy

0

Có lẽ đây là hữu ích cho ai đó:

public Dictionary<string, int> myDictionary = new Dictionary<string, int>(); 
public string myCurrentKey = "some key 5"; 
for (int i = 1; i <= 10; i++) { 
    myDictionary.Add(string.Format("some key {0}", i), i); 
} 

private void MoveIndex(int dir) { // param "dir" can be 1 or -1 to move index forward or backward 
    List<string> keys = new List<string>(myDictionary.Keys); 
    int newIndex = keys.IndexOf(myCurrentKey) - dir; 
    if (newIndex < 0) { 
     newIndex = myDictionary.Count - 1; 
    } else if (newIndex > myDictionary.Count - 1) { 
     newIndex = 0; 
    } 

    myCurrentKey = keys[newIndex]; 
} 

Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 5 
MoveIndex(1); 
Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 6 
MoveIndex(-1); 
MoveIndex(-1); 
Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 4 
Các vấn đề liên quan