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

Есть ли отсортированный тип коллекции в .NET?

Я ищу контейнер, который хранит все его элементы в порядке. Я посмотрел на SortedList, но для этого требуется отдельный ключ и не позволяет дублировать ключи. Я мог бы просто использовать несортированный контейнер и явно сортировать его после каждой вставки.

Использование:

  • Временная вставка
  • Частый обход в порядке
  • Идеально не работает с ключами отдельно от фактического объекта, используя функцию сравнения для сортировки.
  • Требуется стабильная сортировка для эквивалентных объектов, но не требуется.
  • Случайный доступ не требуется.

Я понимаю, что могу просто создать сбалансированную древовидную структуру, мне просто интересно, существует ли в этой структуре уже такой зверь.

4b9b3361

Ответ 1

Возможно, вы захотите взглянуть на Wintellect Power Collections. Он доступен на CodePlex и содержит довольно много коллекций, которые очень полезны. Коллекция OrderedBag в проекте - именно то, что вы ищете. Он по существу использует красно-черное дерево, чтобы обеспечить довольно эффективную сортировку.

Ответ 2

Просто чтобы сделать комментарий EBarr в качестве ответа, SortedSet<T> начиная с .NET 4.0. Конечно, это набор, что означает, что у вас не может быть дубликатов.

Ответ 3

Я бы расширил ваш собственный класс списка, который, как вы упомянули, просто сортирует после каждой вставки. Так как ваши вставки нечасты, производительность будет минимальной, и сортировка сортированного списка будет быстро, в любом случае. Расширьте общий список и переопределите метод "Добавить" для сортировки сразу. Если производительность становится проблемой, вы можете вставить ее, чтобы сэкономить некоторое время. Кроме того, вы можете поставить в очередь свои вставки, чтобы сделать одну прокрутку для всех значений, которые вы хотите вставить.

Ответ 4

Если вы просто хотите придерживаться стандартных коллекций, то функция Sort(IComparer<>) класса List<> - это тот, который часто игнорируется. Все, что вам нужно сделать, это создать подходящий Comparer<> для ваших объектов. Например:

public class PositionDateComparer : IComparer<VehiclePosition>
{
    public int Compare(VehiclePosition x, VehiclePosition y)
    {
        if (x.DateTime == DateTime.MinValue)
        {
            if (y.DateTime == DateTime.MinValue)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }

            // If x is null and y is not null, y
            // is greater. 
            return -1;
        }

        // If x is not null...
        //
        if (y.DateTime == DateTime.MinValue)
        // ...and y is null, x is greater.
        {
            return 1;
        }

        // ...and y is not null, compare the dates
        //
        if (x.DateTime == y.DateTime)
        {
            // x and y are equal
            return 0;
        }

        if (x.DateTime > y.DateTime)
        {
            // x is greater
            return 1;
        }

        // y is greater
        return -1;
    }
}

Затем просто выполните vehiclePositionsList.Sort(new PositionDateComparer()), когда вы хотите отсортировать список перед его доступом. Я понимаю, что это может быть не так просто, как контейнер, который автоматически сортируется каждый раз, когда вы добавляете новый объект, но для многих (например, для меня!) Этого может быть достаточно для успешного выполнения задания без каких-либо дополнительных библиотек.

Ответ 5

Как я упоминал ранее сегодня here, C6 Generic Collection Library имеет подходящий контейнер для вас.

Ответ 6

Если ключ также является атрибутом объекта, вы можете попробовать System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. Это абстрактный класс, но если ваш ключ является просто свойством элемента, то он действительно прост из-за этого.

Ответ 7

Вот старый трюк, который я использовал в VB6 для сортировки в алфавитном порядке: используйте объект ListBox System.Windows.Forms и установите для свойства "Сортировка" значение true. В С# вы можете вставить любой объект в список, и он будет сортировать объект по алфавиту с помощью значения ToString():

для модуля класса:


с использованием System.Windows.Forms;

    static void Main(string[] args)
    {
        ListBox sortedList = new ListBox();
        sortedList.Sorted = true;

        sortedList.Items.Add("foo");
        sortedList.Items.Add("bar");
        sortedList.Items.Add(true);
        sortedList.Items.Add(432); 

        foreach (object o in sortedList.Items)
        {
            Console.WriteLine(o);
        }

        Console.ReadKey();
    }

Это отобразит:

432
бар
Foo
Истинные