0

I have a list of objects. This object has a field called val. This value shouldn't be smaller than zero but there are such objects in this list. I want to replace those less-than-zero values with zero. The easiest solution is

foreach(Obj item in list)
{
    if (item.val < 0)
    {
        item.val = 0;
    }
}

But I want to do this using LINQ. The important thing is I do not want a list of updated elements. I want the same list just with the necessary values replaced. Thanks in advance.

Ahmet
  • 41
  • 1
  • 6
  • Does this answer your question? [LINQ equivalent of foreach for IEnumerable](https://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet) – Cleptus May 28 '21 at 11:37
  • LINQ queries, it doesn't modify anything. You can use `Where(it=>it.val<0)` to retrieve items with negative values, but modifications still have to be done in a loop – Panagiotis Kanavos May 28 '21 at 11:37
  • From where comes requirement "using LINQ" and why? – Sinatr May 28 '21 at 11:38
  • 1
    BTW what you have now is fine, and *faster* than LINQ. Why do you want to change it? – Panagiotis Kanavos May 28 '21 at 11:39
  • 1
    It is not a neccesity. I am learning LINQ and thought I could accomplish this using LINQ. But it seems LINQ (as the name suggests) is for querying rather than updating. Thanks for the comments. – Ahmet May 28 '21 at 11:44
  • You would use Select with ternary operator like this. list.Select( item => item.val < 0 ? 0 : item.val ); – b0neng4 May 28 '21 at 11:47

3 Answers3

2

As I read the comments I realized what I wanted to do is less efficient and pointless. LINQ is for querying and creating new collections rather than updating collections. A possible solution I came across was this

list.Select(c => { if (c.val < 0 ) c.val= 0; return c;}).ToList();

But my initial foreach solution is more efficient than this. So dont make the same mistake I do and complicate things.

Ahmet
  • 41
  • 1
  • 6
1

you can try this one, which is faster because of parallelism

Parallel.ForEach(list, item =>
{
    item.val = item.val < 0 ? 0 : item.val;
});

The Parallel ForEach in C# provides a parallel version of the standard, sequential Foreach loop. In standard Foreach loop, each iteration processes a single item from the collection and will process all the items one by one only. However, the Parallel Foreach method executes multiple iterations at the same time on different processors or processor cores. This may open the possibility of synchronization problems. So, the loop is ideally suited to processes where each iteration is independent of the others

More Details - LINK

1

loop 'for' is faster than 'foreach' so you can use this one

          for (int i = 0; i < list.Count; i++)
            {
                if(list[i].val <= 0)
                {
                    list[i].val = 0;
                }
            }
Baskovli
  • 530
  • 5
  • 13
  • 1
    it should be `i < list.Count` not greater. Also not that OP said it's a list, so you should use Count instead of Length – Magnetron May 28 '21 at 12:42