7

Is there a LINQ method to modify items in a collection, such as simply setting a property of each item in a collection? Something like this:

var items = new []{ new Item { IsActive = true } }
var items = items.Transform(i => i.IsActive = false)

where Touch enumerates each item and applies the transformation. BTW, I am aware of the SELECT extension method, but this would require I expose a method on the type that does this transformation and return the same reference.

var items = items.Select(i => i.Transform())

where Item.Transform returns does the transformation and return the same instance.

TIA

DeCaf
  • 6,026
  • 1
  • 29
  • 51
Klaus Nji
  • 18,107
  • 29
  • 105
  • 185
  • possible duplicate of [LINQ equivalent of foreach for IEnumerable](http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet) – Grant Thomas Oct 15 '11 at 18:56
  • The difference between the first and the second is that the first actually changes the collection while the other returns a new one. – Tetaxa Oct 15 '11 at 18:59
  • `var items = items.Select( i => { i.IsActive = false; return i; })` – Frode Nilsen Jul 07 '16 at 12:52

4 Answers4

14

No, there are no methods in standard LINQ that allows you to modify items in a collection. LINQ is for querying collections and not for causing side-effects (e.g., mutating the items). Eric Lippert goes into the idea in more detail in his blog post: “foreach” vs “ForEach”.

Just use a loop.

foreach (var item in items)
{
    item.IsActive = false;
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • Thanks for response. This is what i will end up doing anyway but I though there was such a method as this is a common thing to do. – Klaus Nji Oct 15 '11 at 18:59
  • @e28Makaveli Note that if your collection is a `List`, then you can use the `ForEach()` method: `list.ForEach(x => x.Property = value);` – dlev Oct 15 '11 at 19:03
2

LINQ is for querying. Use a simple loop if you want to modify. Just use the right tool for the right job. LINQ is not a messiah for everything.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • True, true but the Select extension is some sort of transformation is it not? I would say LINQ is for querying and enumerating over collections. – Klaus Nji Oct 15 '11 at 18:57
  • @e28Makaveli: `Select` is for projecting. That is not the same as mutating nor transforming. – jason Oct 15 '11 at 19:01
  • @e28Makaveli, the Select extension method returns a new IEnumerable, it doesn't modify the original which is what you are trying to do. It's only for projecting. – Darin Dimitrov Oct 15 '11 at 19:02
  • I do not see the difference between projecting and transforming. You can use Select to transform one collection of type T to another collection of type T1. This is a projection but is this also not a transformation? – Klaus Nji Oct 15 '11 at 19:09
  • @e28Makaveli, the difference is that Select returns a new resultset => that's projecting. A transformation is when you modify the original collection. – Darin Dimitrov Oct 15 '11 at 19:11
  • @e28Makaveli: A projection (in the mathematical sense) does not modify the item, it merely creates an alternate representation of the value. e.g., 3D point projected onto a 2D plane. A transformation (also in the mathematical sense) changes the item in some way. e.g., translating (moving) a point from one position to another. The same properties hold here. The `Select()` method simply projects the collection of items to another representation. – Jeff Mercado Oct 15 '11 at 19:19
1

There's a ForEach() on List, so you can do items.ToList().ForEach(i => i.IsActive = false). You might want to read this though.

Tetaxa
  • 4,375
  • 1
  • 19
  • 25
  • 1
    It makes me cringe when I see people take perfectly good collections of items and convert it to a new list so they can use that method... – Jeff Mercado Oct 15 '11 at 19:01
  • Not LINQ but this is sort of what i am looking for. Thanks. – Klaus Nji Oct 15 '11 at 19:02
  • @JeffMercado, my method returns an IEnumerable. I can return List or array if I want. No, I am not creating a new collection just to use ForEach. – Klaus Nji Oct 15 '11 at 19:05
  • @e28Makaveli: I'm not saying that using the `List.ForEach()` method is bad, I'm saying that given a collection that is not declared as a list, creating a new list just to use it is. If you have a list of items from the start, then I would welcome its use (but personally would prefer not to). – Jeff Mercado Oct 15 '11 at 19:08
  • @JeffMercado yes, that would make me cringe too .... creating a new List just to use one of its APIs. Many things wrong with that. This is not what i am doing though. – Klaus Nji Oct 15 '11 at 19:14
0

The documentation page on MSDN for the Enumerable class lists all LINQ methods, and unfortunately no method there does what you want. LINQ is a query language and is not intended to modify collections. It is functional in its nature, meaning that it doesn't modify the collection it operates on, rather it returns a new enumerable.

For your purposes it is better to simply use a foreach loop, or if you feel the need write your own extension method to do what you want, eg.

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

which could then be used as you wanted:

items.ForEach(i => i.IsActive = false)
DeCaf
  • 6,026
  • 1
  • 29
  • 51