2012-10-20 5 views
33

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

注:リストには複数の項目が含まれています。

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

そして、このLINQクエリ(ラムダ式を使用して)が、上部foreachループとしての同じではないが、それだけで、リストから1つのアイテム(一列)を返します!

私が欲しいのは、それはすべての項目(すべての行)を返し、ONLY適切なもの(WHERE拡張子の方法(複数可)で指定した項目をchnagesこと、である

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

注:これらの2例私は繰り返しますが、linqは1つの項目(1行)しか返しません。これは私が望んでいないものです。また、foreachループのようにリストからすべての項目を必要とします。任意のアイテムを削除してください)

+5

*なぜ*ラムダ式を使用しますか? 'foreach'コードはうまく動作し、シンプルです。 LINQは*データを照会するものであり、変更するものではありません。 –

+1

定義上、一致するレコードのみを返します。基本的には:それはあなたが望むものではありません - ちょうどforeachを使用 –

+0

こんにちはジョン、私は、バッターと速いforeachループを知っていますが、私は、すべてthatsを学ぶことはありません。いくつかの "小さな"コードはうまくいくでしょう。しかし、その点はほとんど噂されている。 –

答えて

64

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

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

新しいリストが作成されます。それは、項目のChopps Name!= "height" – Tilak

+0

新しいリストを作成します - そして、それはWHERE句に基づく項目だけを返します。私が望む一例ではありません。 –

+0

@MitjaBonca私の悪い、私はあなたの質問を誤解しました。上記の私の編集を参照してください。 – McGarnagle

2

あなたは声明のラムダで投影を使用することができますが、元foreachループは、より読みやすいと場所でリストを編集するのではなく、新しいリストを作成しています。

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

拡張メソッド

public static void 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(); 
+0

ブロックするのを避けることはできますか?多分選択拡張メソッドを定義するには? –

+0

はい、独自の拡張メソッドを定義することができますが、元のforeachはあまりあいまいでなく維持しやすく、新しいリストを作成してコストがかかることはありません。 – devdigital

+0

私はcusom extemsionメソッドを実行する方法を知っていますが、私はコードに関して「短い」方法でそれを行うことが可能かどうか疑問に思っていましたか? @Robinが示した例のように、彼のコードは機能しません! –

-2

あなたはこのような何か行うことができます。

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

をしかしLINQは、あなたがしたい ながら照会するためであるので、私はむしろforeachを使用することを選ぶだろうデータを編集します。

+0

私はこれまでにこれをトライードしていましたが、例外があります: "無効な匿名型メンバー宣言子。匿名型メンバーはメンバー割り当て、単純な名前またはメンバーアクセスで宣言する必要があります。"これは "s.Value = 30"のためです。 –

+0

例ではありません。 –

8

私はおそらくあなたがすべての項目を保持する場合、元のリストへの参照を保持し、(私はそのていない純粋なLINQを知っている)これでいいと思うし、あなたが更新された値が存在しているはずです。

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

おおよそlist.Find(x => x.Name == "height").Value = 20; これは問題なく動作します。私は古い投稿を知っていますが、なぜ誰もこれを示唆していないのだろうかと疑問に思っただけです。このコードには欠点がありますか?

+0

'list.Find(x => x.Name ==" height ")'が何も返さない場合、エラーが発生します。[NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。] ' –

+0

いつでもnullを実行できます実際に値を変更する前に確認してください。 –

関連する問題