如何将List <T>项目动态添加到IEnumerable <T>

时间:2019-11-07 09:26:45

标签: c# linq ienumerable

代码

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列表中以比较每个列表的数据?

我尝试了很多方法,例如转换为列表,添加,追加,Concat,但没有任何效果。

还有其他最佳方法可以比较N个列表吗?

代码输出:1 2

3 个答案:

答案 0 :(得分:1)

您可以创建列表列表,并将列表动态添加到该列表中。像这样:

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)

答案 1 :(得分:0)

您可以做的是允许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;
        }
    );
}

答案 2 :(得分:-2)

  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();