64

私はいくつかのリストを持っています(ここで、Tはカスタムクラスであり、クラスにはいくつかのプロパティがあります)。Lambda式を使用してその中の1つ以上の値を変更する方法を知りたいので、結果は次のforeachループと同じになります。

注:リストには、内部に複数のアイテムが含まれています(複数の行)

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

これはlinqクエリ(Lambda式を使用)ですが、上位のforeachループと同じではなく、リストから1つのアイテム(1行)のみを返します。

私が欲しいのは、それがすべてのアイテム(すべての行)を返し、適切なもの(WHERE拡張メソッドで指定されたアイテム)のみを変更することです。

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

注:これら2つの例は同じではありません!繰り返しますが、linqは1つのアイテム(1行)しか返しません。これは不要です。リストからすべてのアイテムも必要です(foreachループのように、変更のみを行いますが、アイテムは削除しません)。 )。

4

7 に答える 7

132

を使用することもできますが、を最初ForEachに変換する必要があります。IEnumerable<T>List<T>

list.Where(w => w.Name == "height").ToList().ForEach(s => s.Value = 30);
于 2012-10-20T08:43:33.650 に答える
13

私はおそらくこれを使用し(純粋なlinqではないことを知っています)、すべてのアイテムを保持したい場合は元のリストへの参照を保持し、更新された値がそこにあることを確認する必要があります:

 foreach (var mc in list.Where(x => x.Name == "height"))  
     mc.Value = 30;
于 2012-10-20T09:06:30.550 に答える
5

ステートメントラムダでプロジェクションを使用することもできますが、元のforeachループの方が読みやすく、新しいリストを作成するのではなく、その場でリストを編集しています。

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

拡張方法

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();
于 2012-10-20T08:45:11.187 に答える
3

list.Find(x => x.Name == "height").Value = 20; これはうまくいきます。私はその古い投稿を知っていますが、なぜ誰もこれを提案しなかったのか疑問に思いましたか?このコードに欠点はありますか?

于 2017-08-24T09:45:44.863 に答える
2

これが私が行う方法です。「リスト」はa <List<t>>であり、tは名前と値のフィールドを持つクラスです。もちろん、他のクラスタイプでも実行できます。

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

これは完璧に機能します!これは、ループロジックのない単純なlinq式です。注意する必要があるのは、結果データセットの行の順序がソースデータセットの行の順序とは異なることだけです。したがって、並べ替えが重要な場合は、最後のlinqクエリで同じorderby句を再現するだけです。

于 2020-05-21T09:50:01.823 に答える
-1

私はこれが古い投稿であることを知っていますが、私は常にアップデータ拡張メソッドを使用していました:

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

于 2020-11-10T09:10:46.400 に答える
-2

あなたはこのようなことをすることができます:

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

ただし、データを編集するときにクエリを実行するforeachために使用することを選択します。LINQ

于 2012-10-20T08:51:17.527 に答える