web-dev-qa-db-fra.com

Changer une valeur dans la liste <T>

J'ai une liste (où T est une classe personnalisée, et classe a certaines propriétés). Je voudrais savoir comment changer une ou plusieurs valeurs en utilisant Lambda Expressions, le résultat sera donc le même que celui ci-dessous:

NOTE: la liste contient plusieurs éléments à l'intérieur (plusieurs lignes)

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

Et c'est la requête linq (utilisant des expressions Lambda), mais ce n'est pas la même chose que la boucle foreach supérieure, elle ne retourne qu'un élément (une ligne) de la liste!

Ce que je veux, c’est qu’il renvoie tous les éléments (toutes les lignes) et ne sélectionne que celui qui convient (les éléments spécifiés dans la ou les méthodes d’extension WHERE).

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

NOTE: ces 2 exemples ne sont pas les mêmes! Je le répète, linq ne renvoie qu'un élément (une ligne), et c’est quelque chose que je ne veux pas, j’ai également besoin de tous les éléments de la liste (comme pour la boucle foreach, il ne modifie que les modifications, mais ne supprime aucun élément).

47
Mitja Bonca

Vous pouvez utiliser ForEach , mais vous devez convertir le IEnumerable<T> à un List<T> première.

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

J'irais probablement avec ceci (je sais que ce n'est pas du pur linq), conservez une référence à la liste d'origine si vous voulez conserver tous les éléments, et vous devriez trouver les valeurs mises à jour qui s'y trouvent:

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

Que diriez-vous de list.Find(x => x.Name == "height").Value = 20; Cela fonctionne bien. Je sais que c'est un ancien post, mais je me demandais simplement pourquoi personne ne l'avait suggéré. Y at-il un inconvénient dans ce code?

3
Aditya Muley

Vous pouvez utiliser une projection avec une instruction lambda, mais la boucle originale foreach est plus lisible et édite la liste à la place plutôt que de créer une nouvelle liste.

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

Méthode d'extension

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();
2
devdigital