C # equivalente a std :: sort e std :: única
Pergunta
Eu tenho uma lista de inteiros em C #. Desejo remover duplicatas. Em C ++ eu iria executá-lo através do std :: sort e depois std :: algoritmos originais para uma maneira muito eficiente de obter a lista única.
Qual é a melhor maneira de fazer a mesma coisa em C #? Em outras palavras, eu estou procurando uma maneira mais elegante de fazer o seguinte código:
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;
}
Solução
Qual versão do .NET você está usando?
Em .NET 3.5 que é tão simples como chamar o distinta () método de extensão e, em seguida, ToArray () se você realmente precisa de um array novamente.
Por exemplo:
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)
Outras dicas
Se você considerando métodos STL como "muito eficiente", então use seguinte:
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);
Para 2,0 equivalente
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);
});
Mesmo com .NET 2.0, você pode obter o mesmo com LINQBridge . Isso será mais fácil de usar com C # 3.0 (mesmo com .NET 2.0), mas deve ser utilizável com C # 2.0 e .NET 2.0 - você simplesmente tem que usar Enumerable.Distinct (x) em vez de x.Distinct ();
É claro, as versões em última análise, estes são apenas pré-embalados do código que você postou anteriormente (give-ou-Take coisas como iterador blocos), então você poderia apenas empurrar esse código em uma classe de utilitário e (re) usá-lo de lá.
Infelizmente eu só tenho .NET 2.0 para trabalhar com
Em uma nota meio caminho relacionado, C # tem um System.Array.Sort método estático que você pode usar para classificar matrizes reais sem o uso de uma coleção.
Eu não sei quão grande é a sua colecção é, mas se você não está lidando com milhares de números inteiros isso pode ser bom o suficiente:
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;
}