property indizadores index how c# .net indexing position set

c# - indizadores - Accediendo al ítem en un índice específico en un ''SortedSet''



indexer syntax c# (2)

¿Cómo puedo acceder al elemento en un índice (posición) específico en un SortedSet ?

A diferencia de SortedList , SortedSet no ofrece una propiedad de Item .

(Además, a diferencia de SortedList , SortedSet obliga a cada uno de sus miembros a ser únicos. Es decir, se garantiza que un SortedSet no contiene duplicados).


Esto se debe a que SortedSet tiene la semántica de un conjunto y no es una construcción de tipo List . En consecuencia, no implementa IList (que le brinda la capacidad de abordar los elementos por índice a través de la propiedad Item ).

Como lo señaló @DavidRR, puede usar el método de extensión Linq Enumerable.ElementAt() . Sin embargo, dado que el almacén de respaldo de SortedSet es un árbol rojo-negro: un árbol binario de altura equilibrada, el acceso a un elemento mediante el índice a través de ElementAt() implica una caminata por el árbol: O (N), el caso más desfavorable y O (N / 2) en promedio, para llegar al artículo deseado. Más o menos lo mismo que atravesar una lista de enlaces individuales para acceder al elemento N th .

Entonces ... para conjuntos grandes, es probable que el rendimiento sea pobre.

Si lo que quieres es una colección única que ofrezca una semántica similar a una matriz, ¿por qué no rodar tu propia implementación de IList<T> que SorteSet<T> singularidad, al igual que hace SorteSet<T> (ignorando los elementos que ya existen en la colección)? Use una List<T> como la tienda de respaldo. Manténgalo en una secuencia ordenada para que pueda usar una búsqueda binaria para determinar si el elemento que se está agregando ya existe. O, simplemente subtipo List<T> y anule los métodos apropiados para obtener la semántica que desea.


EDITAR: Un conjunto ordinario (no ordenado) como HashSet<T> administra sus elementos sin ningún orden en particular. Por lo tanto, el índice de un elemento en particular en un conjunto no ordenado no tiene ningún significado en particular.

Sin embargo, en contraste, tiene sentido semántico solicitar un elemento por su posición (índice) en un conjunto de SortedSet . ¿Por qué molestarse con la sobrecarga de una colección ordenada, de lo contrario?

Dicho esto, para un pequeño SortedSet donde el rendimiento no es un problema (consulte el ejemplo a continuación), el método de extensión Linq Enumerable.ElementAt() proporciona un medio conveniente para recuperar un elemento por su índice. Sin embargo, para un gran SortedSet en el que el rendimiento en tiempo de ejecución de la recuperación de un elemento es primordial, considere implementar una colección personalizada como @Nicholas Carey describe en su respuesta .

Respuesta original:

Puede acceder a un elemento de interés por su índice (posición) desde su SortedSet través del método Enumerable.ElementAt() :

var item = mySortedSet.ElementAt(index);

Demostración:

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); } }

Rendimiento esperado:

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''!