簡體   English   中英

在C#linq中的多個列表中查找常見項目

[英]Find common items in multiple lists in C# linq

我進行了搜索,但僅找到與兩個列表相關的答案。 但是當他們超過兩個的時候呢?

List 1 = 1,2,3,4,5
List 2 = 6,7,8,9,1
List 3 = 3,6,9,2,0,1
List 4 = 1,2,9,0,5
List 5 = 1,7,8,6,5,4
List 6 = 1
List 7 =

如何獲得常見物品? 如您所見,其中一個是空的,所以公用將是空的,但是我需要跳過空列表。

您可以鏈接Intersect

List<int> List1 = new List<int> {1, 2, 3, 4, 5};
List<int> List2 = new List<int> { 6, 7, 8, 9, 1 };
List<int> List3 = new List<int> { 3, 6, 9, 2, 0, 1 };
List<int> List4 = new List<int> { 1, 2, 9, 0, 5 };
List<int> List5 = new List<int> { 1, 7, 8, 6, 5, 4 };
List<int> List6 = new List<int> { 1 };

List<int> common = List1
  .Intersect(List2)
  .Intersect(List3)
  .Intersect(List4)
  .Intersect(List5)
  .Intersect(List6)
  .ToList();
var data = new [] {
    new List<int> {1, 2, 3, 4, 5},
    new List<int> {6, 7, 8, 9, 1},
    new List<int> {3, 6, 9, 2, 0, 1},
    new List<int> {1, 2, 9, 0, 5},
    new List<int> {1, 7, 8, 6, 5, 4},
    new List<int> {1},
    new List<int> {},
    null
};

IEnumerable<int> temp = null;
foreach (var arr in data)
    if (arr != null && arr.Count != 0)
        temp = temp == null ? arr : arr.Intersect(temp);
var data = new List<List<int>> {
    new List<int> {1, 2, 3, 4, 5},
    new List<int> {6, 7, 2, 8, 9, 1},
    new List<int> {3, 6, 9, 2, 0, 1},
    new List<int> {1, 2, 9, 0, 5},
    new List<int> {1, 7, 8, 6, 2, 5, 4},
    new List<int> {1, 7, 2}
};


List<int> res = data
    .Aggregate<IEnumerable<int>>((a, b) => a.Intersect(b))
    .ToList();

顯式給出了Aggregate的類型,否則兩個List的聚合也必須是List。 它可以很容易地適應並行運行:

List<int> res = data
    .AsParallel<IEnumerable<int>>()
    .Aggregate((a, b) => a.Intersect(b))
    .ToList();

編輯

除了...它不會並行運行。 問題是對IEnumerable的操作被推遲了,因此,即使它們在並行上下文中進行邏輯合並,實際的合並也會在單線程的ToList()發生。 對於並行執行,最好保留IEnumerable並返回到列表:

List<int> res = data
    .AsParallel()
    .Aggregate((a, b) => a.Intersect(b).ToList());

一種方法是使用HashSet 您可以將第一個集合的項目放入哈希中,然后在第一個集合之后進行迭代,並創建一個新的哈希,將當前集合中的項目添加到哈希中。 最后,您可以將該通用哈希集分配給整個哈希集,如果每個哈希集都是空的,則將其破壞。 最后,您只需返回整個哈希集。

public IEnumerable<T> CommonItems<T>(IEnumerable<IEnumerable<T>> collections)
{
    if(collections == null)
        throw new ArgumentNullException(nameof(collections));

    using(var enumerator = collections.GetEnumerator())
    {
        if(!enumerator.MoveNext())
            return Enumerable<T>.Empty();

        var overall = new HashSet<T>(enumerator.Current);
        while(enumerator.MoveNext())
        {
            var common = new HashSet<T>();
            foreach(var item in enumerator.Current)
            {
                if(hash.Contains(item))
                    common.Add(item);
            }

            overall = common;
            if(overall.Count == 0)
                break;
        }

        return overall;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM