Question

J'ai une liste d'entiers en C #. Je souhaite supprimer les doublons. En C ++, je le ferais passer par les algorithmes std :: sort puis std :: unique pour obtenir un moyen très efficace d’obtenir la liste unique.

Quelle est la meilleure façon de faire la même chose en C #? En d'autres termes, je recherche un moyen plus élégant de créer le code suivant:

    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;
    }
Était-ce utile?

La solution

Quelle version de .NET utilisez-vous?

Dans .NET 3.5, il suffit d'appeler le Méthode d’extension Distinct () , puis ToArray () si vous avez vraiment besoin d'un tableau à nouveau.

Par exemple:

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)

Autres conseils

Si vous considérez les méthodes STL comme "très efficaces", utilisez les méthodes suivantes:

       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);

Pour l'équivalent 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);
});

Même avec .NET 2.0, vous pouvez obtenir le même résultat avec LINQBridge . Ce sera plus facile à utiliser avec C # 3.0 (même avec .NET 2.0), mais devrait être utilisable avec C # 2.0 et .NET 2.0 - vous devrez simplement utiliser Enumerable.Distinct (x) plutôt que x.Distinct ();

Bien sûr, en fin de compte, il s’agit simplement de versions pré-conditionnées du code que vous avez posté précédemment (donner ou prendre des choses comme des blocs d’itérateur), vous pouvez donc simplement insérer ce code dans une classe d’utilitaires et le (ré) utiliser à partir de là-bas.

Hélas, je ne dispose que de .NET 2.0 pour travailler avec

Sur une note reliée à mi-chemin, C # a un System.Array.Sort , méthode statique que vous pouvez utiliser pour trier des tableaux réels sans utiliser de collection.

Je ne sais pas quelle est la taille de votre collection, mais si vous n'avez pas affaire à des milliers d'entiers, cela pourrait suffire:

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;
  }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top