LINQ equivalent of foreach for IEnumerable

后端 未结 22 2153
夕颜
夕颜 2020-11-21 22:54

I\'d like to do the equivalent of the following in LINQ, but I can\'t figure out how:

IEnumerable items = GetItems();
items.ForEach(i => i.DoS         


        
相关标签:
22条回答
  • 2020-11-21 23:43

    ForEach can also be Chained, just put back to the pileline after the action. remain fluent


    Employees.ForEach(e=>e.Act_A)
             .ForEach(e=>e.Act_B)
             .ForEach(e=>e.Act_C);
    
    Orders  //just for demo
        .ForEach(o=> o.EmailBuyer() )
        .ForEach(o=> o.ProcessBilling() )
        .ForEach(o=> o.ProcessShipping());
    
    
    //conditional
    Employees
        .ForEach(e=> {  if(e.Salary<1000) e.Raise(0.10);})
        .ForEach(e=> {  if(e.Age   >70  ) e.Retire();});
    

    An Eager version of implementation.

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enu, Action<T> action)
    {
        foreach (T item in enu) action(item);
        return enu; // make action Chainable/Fluent
    }
    

    Edit: a Lazy version is using yield return, like this.

    public static IEnumerable<T> ForEachLazy<T>(this IEnumerable<T> enu, Action<T> action)
    {
        foreach (var item in enu)
        {
            action(item);
            yield return item;
        }
    }
    

    The Lazy version NEEDs to be materialized, ToList() for example, otherwise, nothing happens. see below great comments from ToolmakerSteve.

    IQueryable<Product> query = Products.Where(...);
    query.ForEachLazy(t => t.Price = t.Price + 1.00)
        .ToList(); //without this line, below SubmitChanges() does nothing.
    SubmitChanges();
    

    I keep both ForEach() and ForEachLazy() in my library.

    0 讨论(0)
  • 2020-11-21 23:44

    You could use the FirstOrDefault() extension, which is available for IEnumerable<T>. By returning false from the predicate, it will be run for each element but will not care that it doesn't actually find a match. This will avoid the ToList() overhead.

    IEnumerable<Item> items = GetItems();
    items.FirstOrDefault(i => { i.DoStuff(); return false; });
    
    0 讨论(0)
  • According to PLINQ (available since .Net 4.0), you can do an

    IEnumerable<T>.AsParallel().ForAll() 
    

    to do a parallel foreach loop on an IEnumerable.

    0 讨论(0)
  • 2020-11-21 23:46

    Many people mentioned it, but I had to write it down. Isn't this most clear/most readable?

    IEnumerable<Item> items = GetItems();
    foreach (var item in items) item.DoStuff();
    

    Short and simple(st).

    0 讨论(0)
提交回复
热议问题