最有效的方法是在没有循环的情况下连接列表中的列表

时间:2011-09-28 18:57:05

标签: c# c#-4.0

public class Unicorn
{
    public List<int> Numbers { get; set; }
}

unicorns.Add(new Unicorn() { Numbers = {1, 2, 3} } );
unicorns.Add(new Unicorn() { Numbers = {4, 5, 6} } );
unicorns.Add(new Unicorn() { Numbers = {7, 8, 9} } );

c#4中最有效的方法是将所有列表连接成一个{1,2,3,4,5,6,7,8,9}列表?

优选地(理想地;优选地;如果有人选择的话)没有环和Linq-less。我和.FindAll纠缠不清,但它没有挖掘它。

4 个答案:

答案 0 :(得分:9)

List<int> theInts = unicorns.SelectMany(unicorn => unicorn.Numbers).ToList();

如果不进行测量,这里唯一让我从性能角度暂停的是.ToList

如果存在TON数字,则ToList可能会反复重新分配其后备阵列。为了避免这种行为,你必须知道要期待多少个数字。

List<int> theInts = new List<int>(expectedSize);
theInts.AddRange(unicorns.SelectMany(unicorn => unicorn.Numbers));

答案 1 :(得分:3)

这是一个完全符合您要求的解决方案: Linq和没有循环 - 我很确定您不想使用此代码:

List<Unicorn> unicorns = new List<Unicorn>();
unicorns.Add(new Unicorn() { Numbers = new List<int>{1, 2, 3} } );
unicorns.Add(new Unicorn() { Numbers = new List<int> { 4, 5, 6 } });
unicorns.Add(new Unicorn() { Numbers = new List<int> { 7, 8, 9 } });

List<int> numbers = new List<int>();
int count = 0;

AddUnicorn: 
if(count < unicorns.Count)
{
    numbers.AddRange(unicorns[count++].Numbers);
    goto AddUnicorn;
}

答案 2 :(得分:3)

您的要求与众不同,但我想您总是可以写:

var numbers = new List<int>();
unicorns.ForEach(unicorn => numbers.AddRange(unicorn.Numbers));

ForEach()可以说是“LINQ-less”,因为它是List<T>的真正成员,而不是IEnumerable<T>上的扩展方法,它实际上是predates LINQ本身

答案 3 :(得分:2)

使用.NET 4.0的Zip运算符:

     var sums = b.Zip(a, (x, y) => x + y)
        .Concat(b.Skip(a.Count()));

如果您想要概括这一点,请检查哪个元素包含更多元素并将其用作上面的“b”