c#将两个不均匀的List交织成一个新的List

本文关键字:List 一个 不均匀 两个 | 更新日期: 2023-09-27 18:12:41

我有两个List,长度都不同。我试图实现的是第三个List,它包含list1的第一个元素,然后是list2的第一个元素,然后是list1的第二个元素,然后是list2的第二个元素,以此类推,直到两个元素中的一个耗尽(它们是不均匀的),然后只添加该列表中的任何剩余项。

result的条目数应该与list1和list2的条目数之和相同。

我不能使用像Union.ToList()这样的东西,因为它不会将两者交织在一起,它只是将例如list1中的所有项目添加到list2的底部,并将其作为结果输出。我尝试了。zip (Linq),然而,这似乎采取了两个元素,并将它们合并成一个元素(即连接两个字符串成一个更长的字符串)。

List<string> list1 = new List<string>(){
            "4041",
            "4040"              
        };
List<string> list2 = new List<string>(){ 
            "4039",
            "4044", 
            "4075", 
            "4010",
            "4100",
            "4070", 
            "4072" 
        };

// Ideal result:    
result = { "4041",
      "4039",
      "4040"  
      "4044",      
      "4075", 
      "4010",
      "4100",
      "4070", 
      "4072" 
}; 

c#将两个不均匀的List交织成一个新的List

int length = Math.Min(list1.Count, list2.Count);
// Combine the first 'length' elements from both lists into pairs
list1.Take(length)
.Zip(list2.Take(length), (a, b) => new int[] { a, b })
// Flatten out the pairs
.SelectMany(array => array)
// Concatenate the remaining elements in the lists)
.Concat(list1.Skip(length))
.Concat(list2.Skip(length));

如果您不需要保持原始列表的完整性,您可以使用while循环从每个列表的前面弹出项:

while(list1.Count > 0 || list2.Count > 0)
{
    if(list1.Count > 0)
    {
        combinedList.Add(list1[0]);
        list1.RemoveAt(0);
    } 
    if(list2.Count > 0)
    {
        combinedList.Add(list2[0]);
        list2.RemoveAt(0);
    } 
}

不像Linq那么简洁,但很容易阅读,并且非常清楚发生了什么。

更长,但可能更有效率

List<string> result = new List<string>();
using (var enumerator1 = list1.GetEnumerator())
using (var enumerator2 = list2.GetEnumerator())
{
    int countBefore;
    do
    {
        countBefore = result.Count;
        if (enumerator1.MoveNext())
            result.Add(enumerator1.Current);
        if (enumerator2.MoveNext())
            result.Add(enumerator2.Current);
    } while (countBefore < result.Count);
}

我想你在找这样的东西:

list1
.SelectMany((x,idx) => new[] { x, list2[idx] })
.Concat(list2.Skip(list1.Count));

Fiddle

我的看法,允许可变数量的IEnumerables相互交错

public static IEnumerable<T> Interleave<T>(params IEnumerable<T>[] enumerables)
        {
            var enumerators = enumerables.Select(e => e.GetEnumerator()).ToList();
            while (enumerators.Any())
            {
                enumerators.RemoveAll(e => {
                    var ended = !e.MoveNext();
                    if (ended) e.Dispose();
                    return ended;
                });
                foreach (var enumerator in enumerators)
                    yield return enumerator.Current;
            }
        }
相关文章: