簡體   English   中英

如何添加列表<t>項目動態到 IEnumerable<t></t></t>

[英]How to add List<T> items dynamically to IEnumerable<T>

代碼

public static void Main()
{
    List<int> list1 = new List<int> {1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> {1, 2, 3 };
    List<int> list3 = new List<int> {1, 2 };
    var lists = new IEnumerable<int>[] { list1, list2, list3 };
    var commons = GetCommonItems(lists);
    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(IEnumerable<T>[] lists)
{
    HashSet<T> hs = new HashSet<T>(lists.First());
    for (int i = 1; i < lists.Length; i++)
        hs.IntersectWith(lists[i]);
    return hs;
}

至於示例,我展示了“list1”“list2”“list3”,但我可能有超過 50 個列表為每個循環生成每個列表。 如何以編程方式將每個“列表”添加到IEnumerable 列表中以比較每個列表的數據?

我嘗試了很多方法,例如轉換為列表、添加、Append、Concat,但沒有任何效果。

有沒有其他最好的方法來比較 N 個列表?

output 代碼:1 2

您可以創建列表列表並將列表動態添加到該列表中。 像這樣的東西:

var lists = new List<List<int>>();
lists.Add(new List<int> {1, 2, 3, 4, 5, 6 });
lists.Add(new List<int> {1, 2, 3 });
lists.Add(new List<int> {1, 2 });

foreach (var list in listSources)
    lists.Add(list);

var commons = GetCommonItems(lists);

要查找交叉點,您可以使用此解決方案,例如: Intersection of multiple lists with IEnumerable.Intersect() (實際上看起來就像您已經在使用的那樣)。

還要確保更改GetCommonItems方法的簽名:

static IEnumerable<T> GetCommonItems<T>(List<List<T>> lists)

您可以做的是允許GetCommonItems方法使用params關鍵字接受可變數量的參數。 這樣,您就無需創建新的列表集合。

但是,不用說,如果源中的列表數量也是可變的,那么使用起來可能會比較棘手。

我還修改了GetCommonItems方法,使其像https://stackoverflow.com/a/1676684/9945524中的代碼一樣工作

public static void Main()
{
    List<int> list1 = new List<int> { 1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> { 1, 2, 3 };
    List<int> list3 = new List<int> { 1, 2 };

    var commons = GetCommonItems(list1, list2, list3); // pass the lists here

    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(params List<T>[] lists)
{
    return lists.Skip(1).Aggregate(
        new HashSet<T>(lists.First()),
        (hs, lst) =>
        {
            hs.IntersectWith(lst);
            return hs;
        }
    );
}

使用現有Main方法的替代解決方案。

編輯:根據此答案中的評論將lists類型更改為List<List<int>>

public static void Main()
{
    List<int> list1 = new List<int> { 1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> { 1, 2, 3 };
    List<int> list3 = new List<int> { 1, 2 };
    var lists = new List<List<int>> { list1, list2, list3 };
    var commons = GetCommonItems(lists);
    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(List<List<T>> lists)
{
    return lists.Skip(1).Aggregate(
        new HashSet<T>(lists.First()),
        (hs, lst) =>
        {
            hs.IntersectWith(lst);
            return hs;
        }
    );
}
  1. IEnumerable 是不可變的,因此您始終應根據需要返回 IEnumerable 的實現。
  2. 如果我理解正確,您想獲得 N 個列表的常見項目。 我會為此使用 LINQ。

我的建議: 1. 制作一個包含所有項目的列表。 =>

var allElements = new List<int>();
  var lists = new List<List<int>>();
foreach (list in lists)
    allElements.AddRange(list);
  1. 采取重復的項目

allElements.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x).ToList();

暫無
暫無

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

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