C # эквивалент std :: sort и std :: unique
Вопрос
У меня есть список целых чисел в C #. Я хочу удалить дубликаты. В C ++ я запускаю его через алгоритмы std :: sort, а затем std :: unique для очень эффективного способа получения уникального списка.
Какой лучший способ сделать то же самое в C #? Другими словами, я ищу более элегантный способ сделать следующий код:
private static int[] unique(int[] ids)
{
IDictionary<int, object> d = new Dictionary<int, object>();
foreach(int i in ids)
d[i] = null;
int[] results = new int[d.Count];
int j = 0;
foreach(int id in d.Keys)
results[j++] = id;
return results;
}
Решение
Какую версию .NET вы используете?
В .NET 3.5 это так же просто, как вызвать Метод расширения Distinct () , а затем ToArray () if вам действительно нужен массив снова.
Например:
int[] x = new[] { 1, 4, 23, 4, 1 };
int[] distinct = x.Distinct().ToArray();
// distinct is now { 1, 4, 23 } (but not necessarily in that order)
Другие советы
если вы рассматриваете методы STL как "очень эффективные", используйте следующее:
var vals = new List<int> { 1, 2, 3, 2, 1, 2, 3, 2, 3, 4, 3, 2, 3 };
vals.Sort();
var uniques = new HashSet<int>(vals);
Для 2.0 эквивалента
List<int> vals = new List<int>();
vals.Add(1);
vals.Add(2);
vals.Add(3);
vals.Add(2);
...
vals.Sort();
List<int> uniques = new List<int>();
vals.ForEach(delegate(int v) {
if (!uniques.Contains(v)) uniques.Add(v);
});
Даже с .NET 2.0 вы можете получить то же самое с LINQBridge . Это будет легче использовать с C # 3.0 (даже с .NET 2.0), но его следует использовать с C # 2.0 и .NET 2.0 - вам просто нужно использовать Enumerable.Distinct (x) вместо x.Distinct (); р>
Конечно, в конечном счете, это просто предварительно упакованные версии кода, которые вы разместили ранее (такие как «иди или забери», такие как блоки итераторов), так что вы можете просто вставить этот код в служебный класс и (повторно) использовать его из есть.
Увы, у меня есть только .NET 2.0 для работы с
На полпути, C # имеет Статический метод System.Array.Sort , который можно использовать для сортировки реальных массивов без использования коллекции.
Я не знаю, насколько велика ваша коллекция, но если вы не имеете дело с тысячами целых чисел, этого может быть достаточно:
public IEnumerable<int> unique(int[] ids)
{
List<int> l = new List<int>();
foreach (int id in ids)
{
if (!l.Contains(id))
{
l.Add(id);
yield return id;
}
}
}
private static List<T> GetUnique<T>(List<T> list) where T : IEquatable<T>
{
list.Sort();
int count = list.Count;
List<T> unique = new List<T>(count);
T last = default(T);
for (int i = 0; i < count; i++)
{
T val = list[i];
if (i != 0 && last.Equals(val)) continue;
last = val;
unique.Add(val);
}
return unique;
}