Change some value inside the List<T>

224,196

Solution 1

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

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

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

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

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.

Share:
224,196
Mitja Bonca
Author by

Mitja Bonca

Updated on November 12, 2020

Comments

  • Mitja Bonca
    Mitja Bonca over 3 years

    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).