C#SortedDictionary中Java的SortedMap.tailMap的等价物

我有使用SortedMap.tailMap java代码。 在我的移植代码中,我有SortedMap = Dictionary 。 我需要一种在C#中复制/模仿tailMap的方法。

我认为如下:

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

这返回一个Dictionary ,我需要返回一个SortedDictionary 。 我可以从Dictionary创建一个SortedDictionary ,但我觉得应该有一个更优雅和性能更好的方法,因为它已经排序。

另一个想法是做类似的事情

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

这应该工作,我不确定在我构建该列表时,排序顺序中的值的添加将如何影响插入的时间。

还有其他想法吗?

  • Java SortedMap
  • C#SortedDictionary

我过去需要这几次,而最简单的方法是做到这一点

  1. 创建并填充可通过索引访问的SortedList
  2. 在IList SortedList.Keys上使用合适的*)BinarySearch方法
  3. 通过IList SortedList.Values访问该值
  4. 将它包装成2.和3.进入扩展方法IEnumerable> Tail(this SortedList list, K fromKey, bool inclusive = true)
  5. 将它作为答案发布在此处,以便我可以复制并粘贴它,从此我只实现了HeadTail并附加了代码 – 见下文。 此外,我添加了TryGetCeiling / Floor / Higher / LowerValue方法 – 从Java的NavigableMap派生的名称,并且可以直接为需要它们的人添加TryGet Key和TryGet Entry。

*)不幸的是,.Net自己的实现仅适用于List ,而不适用于IList 。 多么浪费……另外,一定要使用一个在找不到物品的情况下返回~x的物品,就像我用Antoine Aubry链接的物品一样,而不是像Lasse V. Karlsen那样总是返回常数的物品。 -1所以不能在这里使用。

 public static class SortedListEx { public static IEnumerable> Head( this SortedList 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> Tail( this SortedList 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(list, binarySearchResult); } public static bool TryGetCeilingValue( this SortedList 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( this SortedList 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( this SortedList 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( this SortedList 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 : IEnumerable> { private readonly SortedList _sortedList; private readonly int _offset; public ListOffsetEnumerable(SortedList sortedList, int offset) { _sortedList = sortedList; _offset = offset; } public IEnumerator> GetEnumerator() { return new ListOffsetEnumerator(_sortedList, _offset); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } class ListOffsetEnumerator : IEnumerator> { private readonly SortedList _sortedList; private int _index; public ListOffsetEnumerator(SortedList sortedList, int offset) { _sortedList = sortedList; _index = offset - 1; } public bool MoveNext() { if (_index >= _sortedList.Count) return false; _index++; return _index < _sortedList.Count; } public KeyValuePair Current { get { return new KeyValuePair( _sortedList.Keys[_index], _sortedList.Values[_index]); } } object IEnumerator.Current { get { return Current; } } public void Dispose() { } public void Reset() { throw new NotSupportedException(); } } } 

这是一个简单的测试

 SortedList l = new SortedList { { 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): 

TreeMap有一个尾部地图。 那是你真正想要的吗?