访问'SortedSet'中指定索引处的项

Dav*_*dRR 17 .net c# indexing position set

如何在?中的指定索引(位置)访问该项SortedSet

不同于SortedList,SortedSet不提供Item房产.

(另外,不同的是SortedList,SortedSet强制每个成员都是唯一的.也就是说,SortedSet保证包含重复.)

Nic*_*rey 14

那是因为a SortedSet具有集合的语义而不是类似List构造.因此,它没有实现IList(这使您能够通过Item属性通过索引来处理项目).

如@DavidRR所述,您可以使用Linq扩展方法Enumerable.ElementAt().然而,由于的后备存储器SortedSet是一个红-黑树-高度平衡的二叉树,通过由索引访问一个元素ElementAt()涉及树的步行- O(N),最坏的情况下和O(N/2)上平均,到达所需的项目.与遍历单链表单以访问第N 项目几乎相同.

所以...对于大型套装,性能可能很差.

如果你想要的是一个独特的收藏,提供类似数组的语义,为什么不推出自己IList<T>的实现,将强制唯一性,就像SorteSet<T>做(忽略已经在colleciton存在的元素的增加).使用a List<T>作为后备存储.按排序顺序维护它,以便您可以使用二进制搜索来确定添加的元素是否已存在.或者,只需子类型List<T>并覆盖适当的方法以获得所需的语义.

  • @DavidRR是的,但我在概念上不喜欢`IEnumerable <T>`的`ElementAt`,因为`IEnumerable <T>`不强制*某个顺序.例如,像'ElementAt`,`Last`等方法对于`HashSet <T>`没有意义.不过,您可以实现`IndexedSortedSet <T>`以避免查找惩罚,但这也意味着您降低了"添加"和"删除"性能. (2认同)

Dav*_*dRR 7

编辑:一个普通(无序)集合,如HashSet<T>以没有特定顺序管理其元素。因此,无序集合中特定元素的索引不具有任何特定含义。

然而,相比之下,通过元素在SortedSet<T>中的位置(索引)来请求元素在语义上是有意义的。为什么要为有序集合的开销而烦恼,否则呢?

也就是说,对于性能不是问题的小型SortedSet<T>(请参见下面的示例),Linq 扩展方法Enumerable.ElementAt()提供了一种通过索引检索项目的便捷方法。但是,对于检索元素的运行时性能至关重要的大型SortedSet<T>,请考虑实现自定义集合,如@Nicholas Carey他的回答中


原答案:

您可以SortedSet通过以下Enumerable.ElementAt<TSource>方法通过索引(位置)访问感兴趣的项目:

var item = mySortedSet.ElementAt(index);
Run Code Online (Sandbox Code Playgroud)

示范:

using System;
using System.Collections.Generic;
using System.Linq;

class SortedSetDemo
{
    static void Main(string[] args)
    {
        var words = new string[]
            {"the", "quick", "brown", "fox", "jumps",
             "over", "the", "lazy", "dog"};

        // Create a sorted set.
        var wordSet = new SortedSet<string>();
        foreach (string word in words)
        {
            wordSet.Add(word);
        }

        // List the members of the sorted set.
        Console.WriteLine("Set items in sorted order:");
        int i = 0;
        foreach (string word in wordSet)
        {
            Console.WriteLine("{0}. {1}", i++, word);
        }

        // Access an item at a specified index (position).
        int index = 6;
        var member = wordSet.ElementAt(index);

        Console.WriteLine("\nThe item at index {0} is '{1}'!", index,
                          member);
    }
}
Run Code Online (Sandbox Code Playgroud)

预期输出:

The set items in sorted order is:
0. brown
1. dog
2. fox
3. jumps
4. lazy
5. over
6. quick
7. the

The item at position 6 is 'quick'!
Run Code Online (Sandbox Code Playgroud)