Change some value inside the List<T>

C#LinqLambdaExpression

C# Problem Overview


I have some list (where T is a custom class, and class has some properties). I would like to know how to change one or more values inside of it by using Lambda Expressions, so the result will be the same as the foreach loop bellow:

NOTE: list contains multiple items inside (multiple rows)

        foreach (MyClass mc in list)  
        {
            if (mc.Name == "height")
                mc.Value = 30;
        }

And this the the linq query (using Lambda expressions), but its not the same as the upper foreach loop, it only returns 1 item (one row) from the list!

What I want is, that it returns all the items (all rows) and ONLY changes the appropriate one (the items specified in the WHERE extension method(s).

list = list.Where(w => w.Name == "height").Select(s => { s.Value = 30; return s; }).ToList();

NOTE: these 2 example are not the same! I repeat, the linq only returns 1 item (one row), and this is something I don't want, I need all items from the list as well (like foreach loop, it only do changes, but it does not remove any item).

C# Solutions


Solution 1 - C#

You could use ForEach, but you have to convert the IEnumerable<T> to a List<T> first.

list.Where(w => w.Name == "height").ToList().ForEach(s => s.Value = 30);

Solution 2 - C#

I'd probably go with this (I know its not pure linq), keep a reference to the original list if you want to retain all items, and you should find the updated values are in there:

 foreach (var mc in list.Where(x => x.Name == "height"))  
     mc.Value = 30;

Solution 3 - C#

You could use a projection with a statement lambda, but the original foreach loop is more readable and is editing the list in place rather than creating a new list.

var result = list.Select(i => 
   { 
      if (i.Name == "height") i.Value = 30;
      return i; 
   }).ToList();

Extension Method

public static IEnumerable<MyClass> SetHeights(
    this IEnumerable<MyClass> source, int value)
{
    foreach (var item in source)
    {
       if (item.Name == "height")
       {
           item.Value = value;
       }
        
       yield return item;
    } 
}

var result = list.SetHeights(30).ToList();

Solution 4 - C#

How about list.Find(x => x.Name == "height").Value = 20; This works fine. I know its an old post, but just wondered why hasn't anyone suggested this? Is there a drawback in this code?

Solution 5 - C#

This is the way I would do it : saying that "list" is a <List<t>> where t is a class with a Name and a Value field; but of course you can do it with any other class type.

    list = list.Where(c=>c.Name == "height")
        .Select( new t(){Name = c.Name, Value = 30})
        .Union(list.Where(c=> c.Name != "height"))
        .ToList();

This works perfectly ! It's a simple linq expression without any loop logic. The only thing you should be aware is that the order of the lines in the result dataset will be different from the order you had in the source dataset. So if sorting is important to you, just reproduce the same order by clauses in the final linq query.

Solution 6 - C#

I know this is an old post but, I've always used an updater extension method:

      public static void Update<TSource>(this IEnumerable<TSource> outer, Action<TSource> updator)
        {
            foreach (var item in outer)
            {
                updator(item);
            }
        }

list.Where(w => w.Name == "height").ToList().Update(u => u.height = 30);

Solution 7 - C#

You can do something like this:

var newList = list.Where(w => w.Name == "height")
              .Select(s => new {s.Name, s.Value= 30 }).ToList();

But I would rather choose to use foreach because LINQ is for querying while you want to edit the data.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMitja BoncaView Question on Stackoverflow
Solution 1 - C#McGarnagleView Answer on Stackoverflow
Solution 2 - C#gmnView Answer on Stackoverflow
Solution 3 - C#devdigitalView Answer on Stackoverflow
Solution 4 - C#Aditya MuleyView Answer on Stackoverflow
Solution 5 - C#DavidView Answer on Stackoverflow
Solution 6 - C#StuView Answer on Stackoverflow
Solution 7 - C#Robin V.View Answer on Stackoverflow