[英]Selecting Unique Elements From a List in C#
如何從列表{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 框架 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<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;
}
}
如果您的 List 中有復雜類型的對象並且想要獲取屬性的唯一值,這是另一種可行的方法:
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<Order>
{
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<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;
}
給貓剝皮的方法有很多,但 HashSet 似乎是為這里的任務而設計的。
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 );
}
輸出:
0 1 2 3 4 5
這是一個沒有 LINQ 的解決方案:
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
// This assumes the numbers are sorted
var noRepeats = new List<int>();
int temp = numbers[0]; // Or .First() if using IEnumerable
var count = 1;
for(int i = 1; i < numbers.Length; i++) // Or foreach (var n in numbers.Skip(1)) if using IEnumerable
{
if (numbers[i] == temp) count++;
else
{
if(count == 1) noRepeats.Add(temp);
temp = numbers[i];
count = 1;
}
}
if(count == 1) noRepeats.Add(temp);
Console.WriteLine($"[{string.Join(separator: ",", values: numbers)}] -> [{string.Join(separator: ",", values: noRepeats)}]");
這打印:
[0,1,2,2,2,3,4,4,5] -> [0,1,3,5]
在 .Net 2.0 中,我非常確定這個解決方案:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.