从C#中的列表中选择唯一元素

如何从列表{0, 1, 2, 2, 2, 3, 4, 4, 5}选择唯一元素{0, 1, 2, 2, 2, 3, 4, 4, 5}以便我得到{0, 1, 3, 5} ,有效地删除重复的所有实例元素{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(); 

确保你使用的是Linq和.NET framework 3.5。

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

C#2.0解决方案:

 static IEnumerable GetUniques(IEnumerable things) { Dictionary counts = new Dictionary(); foreach (T item in things) { int count; if (counts.TryGetValue(item, out count)) counts[item] = ++count; else counts.Add(item, 1); } foreach (KeyValuePair kvp in counts) { if (kvp.Value == 1) yield return kvp.Key; } } 

如果列表中有复杂的类型对象并希望获取属性的唯一值,则这是另一种方法:

 var uniqueValues= myItems.Select(k => k.MyProperty) .GroupBy(g => g) .Where(c => c.Count() == 1) .Select(k => k.Key) .ToList(); 

或者获得不同的值:

 var distinctValues = myItems.Select(p => p.MyProperty) .Distinct() .ToList(); 

如果您的属性也是复杂类型,则可以为Distinct()创建自定义比较器,例如Distinct(OrderComparer),其中OrderComparer可能如下所示:

 public class OrderComparer : IEqualityComparer { public bool Equals(Order o1, Order o2) { return o1.OrderID == o2.OrderID; } public int GetHashCode(Order obj) { return obj.OrderID.GetHashCode(); } } 

如果Linq不可用,因为您必须支持无法升级的遗留代码,则声明一个Dictionary,其中第一个int是数字,第二个int是出现的数量。 循环浏览列表,加载字典。 完成后,循环遍历“词典”,仅选择出现次数为1的元素。

我相信马特的意思是说:

  static IEnumerable GetUniques(IEnumerable things) { Dictionary uniques = new Dictionary(); foreach (T item in things) { if (!(uniques.ContainsKey(item))) { uniques.Add(item, true); } } return uniques.Keys; } 

皮肤猫的方法有很多,但HashSet似乎是为了这个任务而做的。

 var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 }; HashSet r = new HashSet(numbers); foreach( int i in r ) { Console.Write( "{0} ", i ); } 

输出:

0 1 2 3 4 5

在.Net 2.0中我非常肯定这个解决方案:

 public IEnumerable Distinct(IEnumerable source) { List uniques = new List(); foreach (T item in source) { if (!uniques.Contains(item)) uniques.Add(item); } return uniques; }