c#将来自2个列表的x个项目组合成3个列表

时间:2017-11-01 10:26:27

标签: c# linq

我有两个List<T>

List<T> listA = new List<T>();
List<T> listB = new List<T>();

每个列表包含一定数量的项目。

我怎样才能创建包含ListA中的2个项目和ListB中的4个项目的List<List<T>>

示例:

public class Item
{
     public string Category { get; set; }
}



List<Item> listA = new List<Item>();

//repeat the code bellow until listA will contain 8 items of category Apple (amount 8 is just an example)
listA.Add(new Item()
{
   Category = "Apple"
});


List<Item> listB = new List<Item>();

//repeat the code bellow until listB will contain 16 items of category Apple (amount 16 is just an example)
listB.Add(new Item()
{
   Category = "Pear"
});

所以ListA包含8个Apple类型的项目,ListB包含16个pear类型的项目。我想创建单独的List<Item>,每个列表包含来自ListA的2个项目和来自ListB的4个项目,因此我将有4个List<Item>

List<Item> list1 // contains 2 items from ListA and 4 items from ListB
List<Item> list2 // contains 2 items from ListA and 4 items from ListB
List<Item> list3 // contains 2 items from ListA and 4 items from ListB
List<Item> list4 // contains 2 items from ListA and 4 items from ListB

现在上面的4个列表可以添加到List

List<List<Item>> items = new List<List<Item>>();
items.Add(list1);
items.Add(list2);
items.Add(list3);
items.Add(list4);

4 个答案:

答案 0 :(得分:3)

原来的问题,

  

我怎样才能创建包含ListA中的2个项目和ListB中的4个项目的List<List<T>>

var result = new List<List<T>> { listA.Take(2).ToList(), listB.Take(4).ToList() };

答案 1 :(得分:3)

这里的核心问题是你需要MoreLinq的细分(制作2和4项组)。之后,它是一个简单的.Zip()列表。

using System.Linq;
using MoreLinq;

var segA   = listA.Segment((x, i) => i % 2 == 0);
var segB   = listB.Segment((x, i) => i % 4 == 0);
var result = segA.Zip(segB, (a, b) => a.Concat(b).ToList()).ToList();

答案 2 :(得分:1)

根据我对你问题的理解,你需要这样的东西。 至于下面提到的“条件”,你必须根据你的情况弄清楚。 一个案例可能是:如果发生这种情况,那么在成对之后,如果剩下1个苹果并且剩下3个梨,那么应该做些什么。

public class AB()
{
    public List<T> AList { get; set; }
    public List<T> BList { get; set; }
}

//code in the function
List<AB> lstAB = new List<AB>();
int takeA = 2;
int takeB = 4;
int skipA = 0;
int skipB = 0;
while(condition)
{
    lstAb.Add(new AB() 
    { 
        AList = listA.Skip(skipA).Take(takeA).ToList(), 
        BList = listB.Skip(skipB).Take(takeB).ToList()
    });

    skipA += takeA;
    skipB += takeB;
};

答案 3 :(得分:1)

对于您想要实现的目标,没有开箱即用的LINQ&#39;方法。 您可以使用第三方库。

或者编写自己的扩展方法:

    public static class Extensions
    {
        public static List<List<TEntity>> ToFixedSizeGroups<TEntity>(this IEnumerable<TEntity> list1, IEnumerable<TEntity> list2, int take1, int take2)
        {
            // check if the collection is a list already
            var list1Enumerated = list1 as IList<TEntity> ?? list1.ToList();
            var list2Enumerated = list2 as IList<TEntity> ?? list2.ToList();

            // If we want to use a single for loop we need to know max-length
            var longerList = list1Enumerated.Count > list2Enumerated.Count ? list1Enumerated : list2Enumerated;
            var grouppedList1 = Enumerable.Range(0, list1Enumerated.Count / take1).Select(x => new List<TEntity>()).ToList();
            var grouppedList2 = Enumerable.Range(0, list2Enumerated.Count / take2).Select(x => new List<TEntity>()).ToList();

            for (var i = 0; i < longerList.Count; i++)
            {
                if (i < list1Enumerated.Count && i / take1 < grouppedList1.Count)
                {
                    grouppedList1[i / take1].Add(list1Enumerated[i]);
                }
                if (i < list2Enumerated.Count && i / take2 < grouppedList2.Count)
                {
                    grouppedList2[i / take2].Add(list2Enumerated[i]);
                }
            }

            return grouppedList1.Where(x => x.Count == take1).Zip(grouppedList2.Where(x => x.Count == take2), (x, y) => x.Concat(y).ToList()).ToList();
        }
    }

使用示例:

List<string> a = new List<string> {"one", "two", "three", "one"};
List<string> b = new List<string> { "four", "five", "four", "five" };

List<List<string>> groups = a.ToFixedSizeGroups(b, 3, 2);