Подтвердить что ты не робот

Доступ к элементу по указанному индексу в "SortedSet"

Как я могу получить доступ к элементу по указанному индексу (позиции) в SortedSet?

В отличии от SortedList, SortedSet не предлагает Item собственности.

(Кроме того, в отличие от SortedList, SortedSet навязывает каждый из его членов должен быть уникальным. То есть, SortedSet гарантированно не содержат дубликатов.)

4b9b3361

Ответ 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 и хранит количество подузлов в каждом узле для доступа к элементу в указанный индекс