2014-09-27 40 views
4

我有使用SortedMap.tailMap的java代碼。在我移植的代碼中,我有SortedMap = Dictionary<IComparable, value>。我需要一種方法來複制/模仿C#中的tailMap。C#中Java的SortedMap.tailMap的等價SortedDictionary

我想過類似如下:

myDictionary.Where(p => p.Key.CompareTo(value) >= 0).ToDictionary

這會返回一個Dictionary,我需要一個SortedDictionary返回。我可以從Dictionary創建一個SortedDictionary,但是我覺得應該有一個更優雅,更完美的方式來完成這個任務,因爲它已經被排序了。

另一個想法是不喜歡

var newSD = new SortedDictionary<k,v>(); 
foreach (var p in oldDictionary.Where(p => p.Key.CompareTo(value) >= 0)) 
    newSD.Add(p.Key, p.Value); 

東西應該工作,我不知道值的排序順序會影響到刀片時機,因爲我建立一個列表如何加入。

還有其他想法嗎?

+0

非常有幫助!謝謝 – Prescott 2015-07-17 04:23:56

回答

0

我需要這個一對夫婦在過去的時間,並AFAIK做到這一點,最簡單的方法是

  1. 創建並填充SortedList<K,V>是通過索引訪問
  2. 一個suitable*) BinarySearch methodIList<K> SortedList.Keys使用
  3. 訪問經由IList<V> SortedList.Values
  4. 值把它包2.和3成一個擴展方法IEnumerable<KeyValuePair<K, V>> Tail(this SortedList<K, V> list, K fromKey, bool inclusive = true)
  5. 在這裏發佈它作爲答案,以便我可以從此複製並粘貼它 我剛剛實施了HeadTail並附加了代碼 - 請參見下文。此外,我添加了TryGetCeiling/Floor/Higher/LowerValue方法 - 從Java的NavigableMap派生的名稱,並且可以直接添加TryGet Key和TryGet需要它們的任何人的輸入。

*)不幸的是.Net自己的實現只適用於List s,而不是IList s。什麼是廢物......另外,一定要使用一個返回~x,以防萬一找不到該物品,就像我通過Antoine Aubry鏈接到的物品一樣,而不是例如。一個由Lasse V. Karlsen總是返回一個常數-1,所以不能在這裏使用。

public static class SortedListEx 
{ 
    public static IEnumerable<KeyValuePair<K, V>> Head<K, V>(
     this SortedList<K, V> list, K toKey, bool inclusive = true) 
    { 
     https://stackoverflow.com/a/2948872/709537 BinarySearch 
     var binarySearchResult = list.Keys.BinarySearch(toKey); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     else if (inclusive) 
      binarySearchResult++; 
     return System.Linq.Enumerable.Take(list, binarySearchResult); 
    } 

    public static IEnumerable<KeyValuePair<K, V>> Tail<K, V>(
     this SortedList<K, V> list, K fromKey, bool inclusive = true) 
    { 
     https://stackoverflow.com/a/2948872/709537 BinarySearch 
     var binarySearchResult = list.Keys.BinarySearch(fromKey); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     else if (!inclusive) 
      binarySearchResult++; 
     return new ListOffsetEnumerable<K, V>(list, binarySearchResult); 
    } 

    public static bool TryGetCeilingValue<K, V>(
     this SortedList<K, V> list, K key, out V value) 
    { 
     var binarySearchResult = list.Keys.BinarySearch(key); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     if (binarySearchResult >= list.Count) 
     { 
      value = default(V); 
      return false; 
     } 
     value = list.Values[binarySearchResult]; 
     return true; 
    } 

    public static bool TryGetHigherValue<K, V>(
     this SortedList<K, V> list, K key, out V value) 
    { 
     var binarySearchResult = list.Keys.BinarySearch(key); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     else 
      binarySearchResult++; 
     if (binarySearchResult >= list.Count) 
     { 
      value = default(V); 
      return false; 
     } 
     value = list.Values[binarySearchResult]; 
     return true; 
    } 

    public static bool TryGetFloorValue<K, V>(
     this SortedList<K, V> list, K key, out V value) 
    { 
     var binarySearchResult = list.Keys.BinarySearch(key); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     else 
      binarySearchResult++; 
     if (binarySearchResult >= list.Count) 
     { 
      value = default(V); 
      return false; 
     } 
     value = list.Values[binarySearchResult]; 
     return true; 
    } 

    public static bool TryGetLowerValue<K, V>(
     this SortedList<K, V> list, K key, out V value) 
    { 
     var binarySearchResult = list.Keys.BinarySearch(key); 
     if (binarySearchResult < 0) 
      binarySearchResult = ~binarySearchResult; 
     if (binarySearchResult >= list.Count) 
     { 
      value = default(V); 
      return false; 
     } 
     value = list.Values[binarySearchResult]; 
     return true; 
    } 

    class ListOffsetEnumerable<K, V> : IEnumerable<KeyValuePair<K, V>> 
    { 
     private readonly SortedList<K, V> _sortedList; 
     private readonly int _offset; 

     public ListOffsetEnumerable(SortedList<K, V> sortedList, int offset) 
     { 
      _sortedList = sortedList; 
      _offset = offset; 
     } 

     public IEnumerator<KeyValuePair<K, V>> GetEnumerator() 
     { 
      return new ListOffsetEnumerator<K, V>(_sortedList, _offset); 
     } 

     IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } 
    } 

    class ListOffsetEnumerator<K, V> : IEnumerator<KeyValuePair<K, V>> 
    { 
     private readonly SortedList<K, V> _sortedList; 
     private int _index; 

     public ListOffsetEnumerator(SortedList<K, V> sortedList, int offset) 
     { 
      _sortedList = sortedList; 
      _index = offset - 1; 
     } 

     public bool MoveNext() 
     { 
      if (_index >= _sortedList.Count) 
       return false; 
      _index++; 
      return _index < _sortedList.Count; 
     } 

     public KeyValuePair<K, V> Current 
     { 
      get 
      { 
       return new KeyValuePair<K, V>(
        _sortedList.Keys[_index], 
        _sortedList.Values[_index]); 
      } 
     } 
     object IEnumerator.Current { get { return Current; } } 

     public void Dispose() { } 
     public void Reset() { throw new NotSupportedException(); } 
    } 
} 

而且這裏有一個簡單的測試

SortedList<int, int> l = 
    new SortedList<int, int> { { 1, 1 }, { 3, 3 }, { 4, 4 } }; 
for (int i = 0; i <= 5; i++) 
{ 
    Console.WriteLine("{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(" +i+ ", true): " 
     + string.Join(", ", l.Head(i, true))); 
    Console.WriteLine("{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(" +i+ ", false): " 
     + string.Join(", ", l.Head(i, false))); 
} 
for (int i = 0; i <= 5; i++) 
{ 
    Console.WriteLine("{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(" +i+ ", true): " 
     + string.Join(", ", l.Tail(i, true))); 
    Console.WriteLine("{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(" +i+ ", false): " 
     + string.Join(", ", l.Tail(i, false))); 
} 

其打印如下:

{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(0, true): 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(0, false): 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(1, true): [1, 1] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(1, false): 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(2, true): [1, 1] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(2, false): [1, 1] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(3, true): [1, 1], [3, 3] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(3, false): [1, 1] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(4, true): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(4, false): [1, 1], [3, 3] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(5, true): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Head(5, false): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(0, true): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(0, false): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(1, true): [1, 1], [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(1, false): [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(2, true): [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(2, false): [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(3, true): [3, 3], [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(3, false): [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(4, true): [4, 4] 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(4, false): 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(5, true): 
{ { 1, 1 }, { 3, 3 }, { 4, 4 } }.Tail(5, false): 
0

TreeMap具有尾巴的地圖。那是你真正想要的嗎?

+0

道歉,我正在尋找反向 - 在C#中的tailMap(我的理解是C#中的TreeMap => SortedDictionary,但可惜,SortedDictionary似乎沒有tailMap – Prescott 2014-09-27 21:27:51