Comment sélectionner les éléments uniques dans la liste {0, 1, 2, 2, 2, 3, 4, 4, 5}
afin d'obtenir {0, 1, 3, 5}
, en supprimant efficacement toutes les occurrences de les éléments répétés {2, 4}
?
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
var uniqueNumbers =
from n in numbers
group n by n into nGroup
where nGroup.Count() == 1
select nGroup.Key;
// { 0, 1, 3, 5 }
var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();
assurez-vous que vous utilisez Linq et .NET Framework 3.5.
Avec lambda ..
var all = new[] {0,1,1,2,3,4,4,4,5,6,7,8,8}.ToList();
var unique = all.GroupBy(i => i).Where(i => i.Count() == 1).Select(i=>i.Key);
Solution C # 2.0:
static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
Dictionary<T, int> counts = new Dictionary<T, int>();
foreach (T item in things)
{
int count;
if (counts.TryGetValue(item, out count))
counts[item] = ++count;
else
counts.Add(item, 1);
}
foreach (KeyValuePair<T, int> kvp in counts)
{
if (kvp.Value == 1)
yield return kvp.Key;
}
}
Voici une autre méthode qui fonctionne si vous avez des objets de type complexe dans votre liste et souhaitez obtenir les valeurs uniques d'une propriété:
var uniqueValues= myItems.Select(k => k.MyProperty)
.GroupBy(g => g)
.Where(c => c.Count() == 1)
.Select(k => k.Key)
.ToList();
Ou pour obtenir des valeurs distinctes:
var distinctValues = myItems.Select(p => p.MyProperty)
.Distinct()
.ToList();
Si votre propriété est également un type complexe, vous pouvez créer un comparateur personnalisé pour Distinct (), tel que Distinct (OrderComparer), où OrderComparer pourrait ressembler à ceci:
public class OrderComparer : IEqualityComparer<Order>
{
public bool Equals(Order o1, Order o2)
{
return o1.OrderID == o2.OrderID;
}
public int GetHashCode(Order obj)
{
return obj.OrderID.GetHashCode();
}
}
Je crois que Matt voulait dire:
static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
Dictionary<T, bool> uniques = new Dictionary<T, bool>();
foreach (T item in things)
{
if (!(uniques.ContainsKey(item)))
{
uniques.Add(item, true);
}
}
return uniques.Keys;
}
Si Linq n'est pas disponible pour vous parce que vous devez prendre en charge le code hérité qui ne peut pas être mis à niveau, déclarez un dictionnaire, où le premier entier est le nombre et le second le nombre d'occurrences. Parcourez votre liste en chargeant votre dictionnaire. Lorsque vous avez terminé, parcourez votre dictionnaire en sélectionnant uniquement les éléments pour lesquels le nombre d'occurrences est 1.
Il y a beaucoup de façons de peler un chat, mais HashSet semble fait pour la tâche.
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
HashSet<int> r = new HashSet<int>(numbers);
foreach( int i in r ) {
Console.Write( "{0} ", i );
}
Le résultat:
0 1 2 3 4 5
En .Net 2.0, je suis à peu près sûr de cette solution:
public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
List<T> uniques = new List<T>();
foreach (T item in source)
{
if (!uniques.Contains(item)) uniques.Add(item);
}
return uniques;
}