Существует ли универсальная коллекция сортированного списка не уникальных ключей в C#?

Я немного удивлен системой.Коллекции.Родовой.Объекта sortedlist, в том, что

  1. это требует от меня использовать <key, value> вместо <value>(comparer)
  2. это позволяет только на входе в значение

Они кажутся причудливыми в том, как я хочу использовать его (Хотя я уверен, что они подходят для других ситуаций). Есть ли другая коллекция, которая не имеет этих двух характеристик?

5 ответов


SortedList<,> - это действительно карта, отсортированный по ключу, а не список. Возможно, неудачное название. Но есть способы, чтобы имитировать то, что вы хотите, в зависимости от ваших требований. Например, вы можете инкапсулировать SortedList<T, int> и добавьте / удалите что-то вроде:

// add
int count;
if(list.TryGetValue(value, out count)) list[value] = count+1;
else list[value] = 1;

в конечном счете, вы можете использовать простой список (List<>) тоже - это зависит от того, что вы делаете.

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


Я не уверен, что это будет соответствовать вашим требованиям. Но вы можете сортировать обычный список. MSDN говорит об этом, но, очевидно, это требует вызова сортировки.


Я попытался найти то же самое: в основном список, который остается упорядоченным, когда вы добавляете в него элементы. Самое близкое, что я нашел до сих пор, - это SortedSet от Goletas.Коллекции, в которых используется реализация дерева AVL:

http://www.goletas.com/solutions/collections/

но этот класс по-прежнему требует, чтобы каждый элемент в списке был уникальным (следовательно, "Set").

возможно, этот класс может быть изменен для поддержки неуникальных элементов.


Я знаю, что это старый вопрос, но я только что наткнулся на этот другой вопрос (C# Сортируемая коллекция, которая позволяет дублировать ключи), что дает решение: используйте свой собственный IComparer с SortedSet! Т. е.

/// <summary>
/// Comparer for comparing two keys, handling equality as being greater
/// Use this Comparer e.g. with SortedSets, SortedLists or SortedDictionaries, that don't allow duplicate keys
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class DuplicateKeyComparer<TKey> : IComparer<TKey> where TKey : IComparable
{
    #region IComparer<TKey> Members

    public int Compare(TKey x, TKey y)
    {
        int result = x.CompareTo(y);

        return result == 0 ? 1 : result; // Handle equality as being greater
    }

    #endregion
}

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

SortedSet<T> mySortedValues = new SortedSet<T>(new DuplicateKeyComparer<T>());

Edit: во-вторых, это, вероятно, плохая идея для чего-либо, кроме SortedSet<T> поскольку вы, вероятно, не сможете искать различные значения, связанные с дубликатами ключей, используя что-либо другое чем foreach цикл; и SortedSet<T> было бы лучше представлено SortedList<TKey,TValue> С TKey, являющимся интересным значением, а TValue-графом (например,int) количества дубликатов этого объекта.


Если это не критично для производительности, вы можете использовать либо

1) Linq OrderBy () или

2) Метод списка Sort ()

посмотреть этот пример

        var list = new List<int>();
        list.Add( 2);
        list.Add( 1);
        list.Add( 3);

        Console.WriteLine("Using Linq OrderBy");
        foreach (int i in list.OrderBy(i=>i))
            Console.WriteLine(i);

        Console.WriteLine("Using List.Sort()");
        list.Sort();
        foreach (int i in list)
            Console.WriteLine(i);