Существует ли в C# универсальная коллекция отсортированных списков неуникальных ключей?
Я немного удивлен System.Collections.Generic.SortedList, в этом
- Это требует от меня использования
<key, value>
вместо<value>
(Comparer) - Это позволяет только на входе на значение
Они кажутся странными в том смысле, как я хочу их использовать (хотя я уверен, что они как раз подходят для других ситуаций). Есть ли другая коллекция, у которой нет этих двух характеристик?
5 ответов
SortedList<,>
действительно карта, отсортированная по ключу, а не список. Возможно, плохое название. Но есть способы подражать тому, что вы хотите, в зависимости от ваших конкретных требований. Вы можете, например, заключить в капсулу SortedList<T, int>
и добавить / удалить что-то вроде:
// add
int count;
if(list.TryGetValue(value, out count)) list[value] = count+1;
else list[value] = 1;
В конечном итоге вы можете использовать простой список (List<>
) тоже - это зависит от того, что вы делаете.
Отчасти, я ожидаю, что привязка данных и т. Д. Затруднит реализацию обычного списка, который сортируется немедленно - вам нужно реализовать множество интерфейсов, чтобы заставить это работать, как обычно, он ожидает, что элемент, который вы добавите, останется в конце.
Я знаю, что это старый вопрос, но я только что натолкнулся на другой вопрос ( Сортируемая коллекция 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>());
Изменить: если подумать, это, вероятно, плохая идея для чего-либо, кроме SortedSet<T>
поскольку вы, вероятно, не сможете искать различные значения, связанные с дублирующимися ключами, используя что-либо, кроме foreach
петля; а также SortedSet<T>
будет лучше представлен SortedList<TKey,TValue>
с TKey, являющимся интересным значением, и TValue, являющимся подсчетом (например, int
) количества дубликатов этого объекта.
Я не уверен, что это будет соответствовать вашим требованиям. Но вы можете отсортировать обычный список. MSDN говорит об этом, но, очевидно, это требует сортировки вызовов.
Я пытался найти то же самое: в основном список, который остается упорядоченным, когда вы добавляете в него элементы. Самым близким, что я нашел, является SortedSet от Goletas.Collections, который использует реализацию дерева AVL:
http://www.goletas.com/solutions/collections/
Но этот класс все еще требует, чтобы каждый элемент в списке был уникальным (отсюда и "Set").
Возможно, этот класс можно изменить для поддержки неуникальных предметов.
Если это не критично для производительности, вы можете использовать либо
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);