5

不确定是否有描述此问题的算法,但是否有任何优雅的方法可以将列表组合成自定义序列。例如:

List<string> list1 = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();

list1.Add("a");
list1.Add("b");
list1.Add("c");

list2.Add("d");
list2.Add("e");
list2.Add("f");

list3.Add("g");
list3.Add("h");
list3.Add("i");

List<string> combined = new List<string>();

我希望组合的内容包含如下序列:

a //First record in list1
d //First record in list2
g //First record in list3
b //Second record in list1
e //Second record in list2
h //Second record in list3
c //Third record in list1 
f //Third record in list2 
i //Third record in list3 

每个列表中的记录数可能不相等。

编辑

当每个列表中的记录数可能不相等时,我的意思是:

List<string> list1 = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();

list1.Add("a");

list2.Add("b");
list2.Add("c");

list3.Add("d");
list3.Add("e");
list3.Add("f");

List<string> combined = new List<string>();

预期成绩:

a //First record in list1
b //First record in list2
d //First record in list3
c //Second record in list2
e //Second record in list3
f //Third record in list3
4

6 回答 6

4

不知道有没有名字。合并?拼接?但是代码很简单。

var lists = new [] { list1, list2, list3 };
var combined = new List<string>(lists.Sum(l => l.Count));    

for (var i = 0; i < lists.Max(l => l.Count); i++)
{
   foreach (var list in lists)
   { 
      if (i < list.Count)
          combined.Add (list[i])
   }
}
于 2013-03-14T09:46:25.910 回答
2
int MaxCount = List1.Count; //Or whatever the highest list count.

            for (int i = 0; i < MaxCount; i++)
                {
                    if( list1.Count > i)
                    combined.Add(list1[i]);

                    if( list2.Count > i)
                    combined.Add(list2[i]);

                    if( list3.Count > i)
                    combined.Add(list3[i]);
                }
于 2013-03-14T09:50:11.627 回答
1

你可以使用这个通用Merge<T>函数:

    public static IEnumerable<T> Merge<T>(params List<T>[] lists)
    {
        var max = lists.Max(list => list.Count());

        for (int i = 0; i < max; i++)
        {
            foreach (var list in lists)
            {
                if (i < list.Count)
                {
                    yield return list[i];
                }
            }
        }
    }

示例用法:

var merged = Merge(list1, list2, list3).ToList();
于 2013-03-14T09:43:54.253 回答
1

不幸的是,它没有内置功能。您应该循环每个列表并将其添加到新的自定义列表中。

例子:

List<string> result = new List<string>();
int listLength = Math.Max(list1.Count, Math.Max(list2.Count, list3.Count)); // get the largest list length
for(int index = 0; index < listLength; i++){
  if(list1.Count > index) result.Add(list1[index);
  if(list2.Count > index) result.Add(list3[index);
  if(list3.Count > index) result.Add(list3[index);
}
于 2013-03-14T09:55:02.437 回答
0

一个快速的 LINQPad 示例:

void Main()
{
    List<string> list1 = new List<string>();
    List<string> list2 = new List<string>();
    List<string> list3 = new List<string>();

    list1.Add("a");
    list1.Add("b");
    list1.Add("c");

    list2.Add("d");
    list2.Add("e");
    list2.Add("f");

    list3.Add("g");
    list3.Add("h");
    list3.Add("i");

    Merge(new[] { list1, list2, list3}, (c1, c2) => c1 + c2).SelectMany(s => s).Dump();
}

IEnumerable<T> Merge<T>(IEnumerable<IEnumerable<T>> sources, Func<T, T, T> combine)
{
    return sources.Aggregate((s1, s2) => s1.Zip(s2, combine));
}

结果是一个IEnumerable<char>,但这很简单,可以List<string>在必要时转换成一个。

于 2013-03-14T10:00:41.900 回答
-2

您可以使用 Concate() 或 AddRange,有关这些方法之间差异的更多信息,请参阅此线程

于 2013-03-14T09:50:29.150 回答