[英]How to find common items across most lists [not all if can't] in C#
我有這樣的清單
List<List<uint>> AllLists = new List<List<uint>>();
List<uint> TestList1 = new List<uint>();
List<uint> TestList2 = new List<uint>();
List<uint> TestList3 = new List<uint>();
TestList1.Add(0x18A);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x670);
TestList2.Add(0x670);
TestList2.Add(0x670);
TestList3.Add(0xBADC0DE); //this one is empty.. but could contain some useless ones (not 0x670).
AllLists.Add(TestList1.ToList());
AllLists.Add(TestList2.ToList());
AllLists.Add(TestList3.ToList());
List<uint> MostCommonOffset = FindCommon(AllLists);
清單1具有:0x18A,0x188,0x188,0x188,0x188,0x188,0x188,0x670
清單2具有:0x670,0x670
清單3是0xBADC0DE。
即使第3個列表不包含答案,它也應該得到答案0x670
..因為它是大多數列表中唯一的一個。
從理論上講,如果第二個或第三個列表包含0x188
,則最好使用它作為更好的答案,因為列表1中有很多它,並且它存在於2個列表中(大多數列表)。 但是它仍然應該給出兩個答案0x670
和0x188
。
如果列表2或列表3也包含0x188
,那么答案應該有2個共同的答案。 0x670
和0x188
這是我以前使用的功能,但是它需要在所有列表中找到一個匹配項..但這並不總是可能的。
public static List<T> FindCommon<T>(List<List<T>> lists)
{
//This checks to make sure all commons are the same in all lists.
List<uint> Counts = new List<uint>();
List<List<T>> Matches = new List<List<T>>();
bool Found = false;
//List<T> curCheck;
foreach (List<T> list in lists)
{
Found = false;
for (int i = 0; i < Counts.Count; i++)
{
if (Matches[i].Count == list.Count)
{
for (int j = 0; j < list.Count; j++)
{
//they not equals
if ((dynamic)Matches[i][j] != (dynamic)list[j])
goto next_loop;
//fully equal, increase count for repeated match found.
if (j == list.Count - 1)
{
Counts[i]++;
Found = true;
break;
}
}
}
next_loop:
if (Found) break;
continue;
}
if (!Found)
{
Counts.Add(1);
Matches.Add(list);
}
}
return Matches[Counts.IndexOf(Counts.Max())];
}
這是一種簡單的方法,它可以檢查所有列表,但不會檢查所有列表中最常見的列表,如果不能,則不會檢查所有列表。
public static List<T> FindCommon<T>(params List<T>[] lists)
{
//This checks to make sure all the commons that are partilly in all lists.
return lists
.SelectMany(x => x)
.Distinct()
.Where(item => lists.All(l => l.Contains(item)))
.ToList();
}
LINQ解決方案有一些解釋。 還有LINQPad調試技巧。
List<List<uint>> AllLists = new List<List<uint>>();
List<uint> TestList1 = new List<uint>();
List<uint> TestList2 = new List<uint>();
List<uint> TestList3 = new List<uint>();
TestList1.Add(0x18A);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x188);
TestList1.Add(0x670);
TestList2.Add(0x670);
TestList2.Add(0x670);
TestList3.Add(0xBADC0DE); //this one is empty.. but could contain some useless ones (not 0x670).
AllLists.Add(TestList1.ToList());
AllLists.Add(TestList2.ToList());
AllLists.Add(TestList3.ToList());
var numbers = AllLists
.Select(x => x
.GroupBy(y => y) // group the numbers in each sub-list
.Select(z => new { Key = z.Key })) // select only the key in each sub-list
.SelectMany(x => x) // flatten the lists
.GroupBy(x => x.Key) // group by the keys
.OrderByDescending(x => x.Count()) // sort the count of keys from largest to smallest
;
var mostCount = numbers
.Select(x => x.Count()) // select the count of keys only
.Take(1) // take one, actually this line is not needed. you can remove it
.FirstOrDefault(); // take the largest count of key (the counts were sorted in previous linq statement)
var numberWithMostCount = numbers
.Where(x => x.Count() == mostCount) // filter the largest count of in the lists
.Select(x => x.Key) // select the key only
;
foreach (var n in numberWithMostCount)
Console.WriteLine(n); // print all key who has the largest count
您可能會注意到,在我先前的編輯中,我在LINQ語句中調用了一些Dump()方法。 我在LinqPad中編寫和調試了代碼。 它具有Dump()方法,可以輕松查看LINQ操作的結果。 假設我在代碼中放了一個Dump()方法(如果太小,請在新標簽頁中打開圖片)。 Dump()方法顯示LINQ方法的執行結果。 您可以在每個Linq方法之后放置一個Dump()方法。 嘗試在任何帶有注釋的行中添加Dump()方法,最好一次添加一個或兩個Dump()。
LasseVågsætherKarlsen的建議。 使用Distinct()刪除重復項。 感謝LasseVågsætherKarlsen。
var numbers = AllLists
.Select(x => x.Distinct()) // remove duplicates
.SelectMany(x => x) // flatten the lists
.GroupBy(x => x) // group by the keys
.OrderByDescending(x => x.Count()) // sort the count of keys from largest to smallest
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.