tags:

views:

102

answers:

3

Supposing I have two classes, Customer and Order, where one Customer can have one-or-many Orders associated to it.

class Customer
{
  Order[] Orders;
}

class Order
{
  int OrderId;
}

If for any given Customer, I want to find all the associated OrderId's, is there an easy way to do that using linq ? Something that gives the same result as the following foreach solution:

List<int> allOrderIds = new List<int>();
foreach (Order thisOrder in thisCustomer)
{
   allOrderIds.Add(thisOrder.OrderId);
}

TIA.

+8  A: 
var allOrderIds = thisCustomer.Orders.Select(o => o.OrderId).ToList();
mquander
Actually yes, this is the better solution. +1
RPM1984
Works great, thank you!
miket2e
+1  A: 

You can use an extension method that many people create:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
    }
}

And use it like this:

thisCustomer.Orders.ForEach(c => allOrderIds.Add(o.OrderId));
RPM1984
BTW - @mquander's solution is better, however i suggest you create the above extension method to add your your "LINQ Toolbelt". It will come in handy.
RPM1984
See also Lippert's comments as to whether this is a good approach or not ... http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx
Hightechrider
Interesting, but i don't agree with him (in this case). Yes - it's less readable, i would'nt be doing it for complex operations (i mainly using it for looped test Assertions). But if you find that unreadable, most likely you will find all lambda expressions unreadable. What i don't understand is why it's implemented for `List<T>` and not `IEnumerable<T>`.
RPM1984
The bulk of his argument is not about readability, but rather that the method would be used for creating side-effects which goes against the functional way of doing things.
FinnNk
@FinnNk - yes, he mentions 'side effects' at least 3 times, but never clearly states what they are. I would generally like to know. Of course it's harder to debug, but i dont see this as a 'side effect'. A side effect in programming would be when something causes unexpected behaviour. The ForEach extension is syntactic sugar for a regular foreach loop. What am i missing?
RPM1984
In the context of functional programming a 'side effect' simply means that executing the function has some effect other than returning a value. That's not to say it's a bad thing (side effects are central to most programs) or that that behaviour is necessarily unexpected. All the other linq methods return values without side effects (if I remember correctly). There are lots of good reasons to avoid side effects when doing functional programming here's one article for example: http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/12/side-effects-and-functional-programming.aspx.
FinnNk
I still don't understand what the `specific side effect of using the ForEach extension method` causes. All a function does is execute an action that `you specify`, x number of times. i get avoiding side effects in functional programming, i'm just yet to see what the actual side effect is in this particular scenario (curiosity more than anything else). I could be going on and on here, but im still yet to be convinced what the specific side effect is.
RPM1984
A side effect in programming is not "when something causes unexpected behaviour." A side effect is when a function changes the state of the system in a way that is observable outside of the function. In this case, the side effect is the action, and the change is that a new element appears in a list.
mquander
@mquander - you mean "in a way that is NOT observable outside of the function". If so, i see the issue now. Thanks for clearing that up.
RPM1984
A: 

Use the select method. You should also keep the Orders as a List if you want to do a lot of linq statements on them.

thisCustomer.Orders.ToList().Select(o => o.OrderId).ToList();
Dan
The first `.ToList()` is pointless.
Hightechrider