Доступ к элементу по указанному индексу в "SortedSet"
Как я могу получить доступ к элементу по указанному индексу (позиции) в SortedSet
?
В отличии от SortedList
, SortedSet
не предлагает Item
собственности.
(Кроме того, в отличие от SortedList
, SortedSet
навязывает каждый из его членов должен быть уникальным. То есть, SortedSet
гарантированно не содержат дубликатов.)
Ответы
Ответ 1
Это потому, что SortedSet
имеет семантику набора и не является конструкцией типа List
. Следовательно, он не реализует IList
(который дает вам возможность обращаться к элементам по индексу с помощью свойства Item
).
Как отмечено @DavidRR, вы можете использовать метод расширения Linq Enumerable.ElementAt()
. Однако, поскольку резервное хранилище SortedSet
является красно-черным деревом - сбалансированным по высоте бинарным деревом, доступ к элементу по индексу через ElementAt()
включает в себя tree walk — O (N), наихудший случай и O (N/2) в среднем, чтобы добраться до нужного пункта. В значительной степени то же самое, что и перемещение односвязного списка для доступа к элементу N th.
Итак... для больших наборов производительность, вероятно, будет низкой.
Если вам нужна уникальная коллекция, которая предлагает подобную массиву семантику, почему бы не свернуть свою собственную реализацию IList<T>
, которая обеспечивала бы уникальность, точно так же, как SorteSet<T>
(игнорируя добавления элементов, которые уже существуют в сборнике), Используйте List<T>
в качестве хранилища резервных копий. Поддерживайте его в отсортированной последовательности, чтобы вы могли использовать двоичный поиск, чтобы определить, существует ли уже добавленный элемент. Или просто подтип List<T>
и переопределить соответствующие методы для получения семантики, которую вы хотите.
Ответ 2
EDIT: Обычный (неупорядоченный) набор, такой как HashSet <T> управляет своими элементами, заказ. Таким образом, индекс конкретного элемента в неупорядоченном множестве не имеет никакого особого значения.
В отличие от этого, тем не менее, семантический смысл запрашивает элемент по его позиции (индексу) в SortedSet <T> . Зачем беспокоиться о накладных расходах заказанной коллекции, в противном случае?
Тем не менее, для небольшого SortedSet <T> , где производительность не вызывает беспокойства (см. пример ниже), метод расширения Linq Enumerable.ElementAt() обеспечивает удобное средство для извлечения элемента по его индексу. Однако для большого SortedSet <T> , где производительность процесса получения элемента имеет первостепенное значение, рассмотрите возможность реализации пользовательской коллекции как @Николас Кэри описывает его ответ.
Исходный ответ:
Вы можете получить доступ к интересующему элементу по его индексу (позиции) из вашего SortedSet
с помощью метода Enumerable.ElementAt<TSource>
:
var item = mySortedSet.ElementAt(index);
Демонстрация:
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);
}
}
Ожидаемый результат:
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'!
Ответ 3
Если вы намереваетесь загрузить данные в набор, а затем получить доступ к набору, используйте HashSet
и ImmutableSortedSet
вместо SortedSet
.
Загрузите ваши данные в HashSet
, затем вызовите ToImmutableSortedSet()
для преобразования в неизменяемый отсортированный набор, который можно проиндексировать.
Ответ 4
Вы можете использовать MCollections, которые вставляют, редактируют, удаляют, ищут и ищут индекс. За время O (Lg (N)) он использует BST и хранит количество подузлов в каждом узле для доступа к элементу в указанный индекс