开发者

Most efficient way to concatenate list within list without a loop

开发者 https://www.devze.com 2023-04-08 05:02 出处:网络
public class Unicorn { public List<int> Numbers { get; set; } } unicorns.Add(new Unicorn() { Numbers = {1, 2, 3} } );
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} } );

What's the most eff开发者_如何转开发icient way in c# 4 to concatenate all the lists into one list of {1, 2, 3, 4, 5, 6, 7, 8, 9 } ?

Preferably (ideally; by preference; if one had a choice) no loops and Linq-less. I tinkered around with .FindAll, but it's not digging it.


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

Without measuring, the only thing in here that gives me pause from a performance perspective is the .ToList

If there are a TON of numbers, it's possible that ToList may repeatedly re-allocate its backing array. In order to escape this behavior, you have to have some idea about how many Numbers to expect.

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


Here's a solution that fully meets your requirements: No Linq and no loop - I'm pretty sure you do not want to use this code though:

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;
}


Your requirements are quite out of the ordinary, but I guess you can always write:

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

ForEach() arguably qualifies as "LINQ-less", since it's a genuine member of List<T>, not an extension method on IEnumerable<T>, and it actually predates LINQ itself.


Using .NET 4.0's Zip operator:

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

If you want to generalize this, check which has more elements and use that as the "b" above

0

精彩评论

暂无评论...
验证码 换一张
取 消