views:

478

answers:

6

I have a foreach loop reading a list of objects of one type and producing a list of objects of a different type. I was told that a lambda expression can achieve the same result.

var origList = List<OrigType>(); // assume populated
var targetList = List<TargetType>(); 

foreach(OrigType a in origList) {
    targetList.Add(new TargetType() {SomeValue = a.SomeValue});
}

Any help would be appreciated- i'm new to lambda and linq thanks, s

+10  A: 

Try the following

var targetList = origList
  .Select(x => new TargetType() { SomeValue = x.SomeValue })
  .ToList();

This is using a combination of Lambdas and LINQ to achieve the solution. The Select function is a projection style method which will apply the passed in delegate (or lambda in this case) to every value in the original collection. The result will be returned in a new IEnumerable<TargetType>. The .ToList call is an extension method which will convert this IEnumerable<TargetType> into a List<TargetType>.

JaredPar
A: 

I believe something like this should work:

origList.Select(a => new TargetType() { SomeValue = a.SomeValue});

Andy White
thanks- i got hung up on a select that jumps right into a lambda without any filtering... this is what i needed.
Stratton
+5  A: 

If you know you want to convert from List<T1> to List<T2> then List<T>.ConvertAll will be slightly more efficient than Select/ToList because it knows the exact size to start with:

target = orig.ConvertAll(x => new TargetType { SomeValue = x.SomeValue });

In the more general case when you only know about the source as an IEnumerable<T>, using Select/ToList is the way to go. You could also argue that in a world with LINQ, it's more idiomatic to start with... but it's worth at least being aware of the ConvertAll option.

Jon Skeet
at first i didn't think i could do this, because i was dealing with an ienumerable (for the source list and it doesnt provide a convertall option) so i called .ToList() on it and now i'm trying convertall - i like it better than putting in a non-filtering 'where'
Stratton
Why would you need a where? If you've only got `IEnumerable<T>` then just call `Select` and `ToList` as per Jared's answer.
Jon Skeet
A: 
var list1 = new List<Type1>();
var list2 = new List<Type2>();

list1.ForEach(item => list2.Add(new Type2() { Prop1 = value1 }));
Chris Arnold
A: 

Here's a simple example..

List<char> c = new List<char>() { 'A', 'B', 'C' };

List<string> s = c.Select(x => x.ToString()).ToList();
Ian P
A: 

I know the "lambda" way is to use Select(), but I've found it harder to debug especially if you have casts and converts or any code to perform the translation. For my next project I will think twice before using .select() and probably go with the fashioned "foreach".

Juan Sagasti