views:

144

answers:

4

Let's say I've got:

Dim los1 as New List(Of String)
los1.Add("Some value")

Dim los2 as New List(Of String)
los2.Add("More values")

What would be the most efficient way to combine the two into a single List(Of String)?

Edit: While I love the solutions everyone has provided, I probably should have also mentioned I'm stuck using the .NET 2.0 framework.

+7  A: 

This depends. If you just want to see a sequence of the two lists then use the Enumerable.Concat mtehod.

Dim combined = los1.Concat(los2)

This will return an IEnemurable(Of String) which contains all of the elements in los1 and los2. It won't allocate a huge new collection but instead will iterate over the 2 separate collections.

JaredPar
especially if need only to foreach them. memory will not be wasted.
Andrey
If you use this method, for the love of God turn Option Infer on. (Otherwise `combined` is an `Object` and VB will let you attempt *anything* with it.) Alternatively, you could just type `Dim combined As IEnumerable(Of String)`... By the way, you've got a lingering semi-colon there ;)
Dan Tao
+4  A: 

JaredPar's answer will give you an object that will enumerate over both lists. If you actually want a List(Of String) object containing these values, it's as simple as:

Dim combined As New List(Of String)(los1.Concat(los2));

EDIT: You know, just because you're using .NET 2.0 doesn't mean you can't roll your own versions of some of the LINQ extension methods you personally find useful. The Concat method in particular would be quite trivial to implement in C#*:

public static class EnumerableUtils {
    public static IEnumerable<T> Concat<T>(IEnumerable<T> first, IEnumerable<T> second) {
        foreach (T item in first)
            yield return item;

        foreach (T item in second)
            yield return item;
    }
}

Then, see here:

Dim los1 as New List(Of String)
los1.Add("Some value")

Dim los2 as New List(Of String)
los2.Add("More values")

Dim combined As New List(Of String)(EnumerableUtils.Concat(los2, los2))

* To be fair, this is a lot more straightforward in C# thanks to the yield keyword. It could be done in VB.NET, but it'd be trickier to provide deferred execution in the same manner that the LINQ extensions do.

Dan Tao
You know, I never thought of recreating the LINQ extensions for my .NET 2.0 projects (although I probably should have).+1 to you and thank you for opening my eyes to something new!
Jason Towne
@Jason: Yeah, the main hiccup that I could see you running into would be the lack of extension methods, making it tougher to get clean-looking code through method chaining. However, this can easily be accomplished by writing a class that wraps an `IEnumerable(Of T)` and provides equivalents of all the LINQ extensions (that you care about) as methods. I have in fact written a library that does precisely this, and was thinking about putting it up on an OSS hosting site. Let me know if you're interested.
Dan Tao
@Dan: I'd definitely be interested in taking a look at that library. It certainly sounds like it would very useful in my situation!
Jason Towne
+1  A: 

Union() potentially, if you want a distinct list of entries (I beleive it only does a distinct), is another alternative.

Brian
You are correct, `Union` does return a list of the distinct values: as explained in the MSDN topic http://msdn.microsoft.com/en-us/library/bb341731.aspx
MarkJ
+4  A: 

I think

los1.AddRange(los2)
Javier Morillo
This works so long as you don't mind that los1 is altered. Also, it is slower than Concat since it will need to allocate memory for the new items in los1.
Ryan Brunner
Yes, I supposed that los1 can be altered. What you say about being slower than Concat is very interesting. Thanks
Javier Morillo
This is the method that worked for me, primarily because I'm stuck using the .NET 2.0 framework.
Jason Towne