web-dev-qa-db-ja.com

Linqスタイル "For Each"

重複している可能性があります:
LinqのIEnumerableに対するforeachの同値

"For each"操作のためのLinqスタイルの構文はありますか?

たとえば、あるコレクションに基づく値を別のコレクションに、すでに存在するものに追加します。

IEnumerable<int> someValues = new List<int>() { 1, 2, 3 };

IList<int> list = new List<int>();

someValues.ForEach(x => list.Add(x + 1));

の代わりに

foreach(int value in someValues)
{
  list.Add(value + 1);
}
167

ToList()拡張メソッドを使用するのが最良の選択です。

someValues.ToList().ForEach(x => list.Add(x + 1));

ForEachを直接実装するBCLには拡張メソッドはありません。


BCLにこれを行う拡張メソッドはありませんが、はまだSystem名前空間のオプションです...プロジェクトに Reactive Extensions を追加した場合

using System.Reactive.Linq;

someValues.ToObservable().Subscribe(x => list.Add(x + 1));

これは、上記のToListの使用と同じ最終結果になりますが、値を直接デリゲートにストリームするため、(理論上)より効率的です。

244
Mark Seemann

Array および List<T> クラスには、既にForEachメソッドがありますが、これは特定の実装のみです。 (ところで、前者はstaticです)。

それがforeachステートメントよりも優れた利点を本当に提供しているかどうかはわかりませんが、すべてのIEnumerable<T>オブジェクトに対してその仕事をするための拡張メソッドを書くことができます。

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
        action(item);
}

これはあなたがあなたの質問に投稿した正確なコードがあなたが望むように働くことを可能にするでしょう。

90
Noldorin

組み込みのものは何もありませんが、それを行うための独自の拡張メソッドを簡単に作成できます。

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    if (source == null) throw new ArgumentNullException("source");
    if (action == null) throw new ArgumentNullException("action");

    foreach (T item in source)
    {
        action(item);
    }
}
30
LukeH

公式のMS行は「機能的な操作ではないため」です(つまり、ステートフルな操作です)。

次のようなことはできませんでした。

list.Select( x => x+1 )

それともあなたが本当にそれをリストの中で必要とするならば:

var someValues = new List<int>( list.Select( x => x+1 ) );
18
stusmith

Linq ForEach拡張子はありません。ただし、Listを直接使用する場合は、ListクラスにForEachメソッドがあります。

それが価値があるもののために、標準的なforeach構文はあなたが望む結果をあなたに与えるでしょう、そしてそれはおそらく読むのがより簡単です:

foreach (var x in someValues)
{
    list.Add(x + 1);
}

もしあなたが大人気なら、Linqスタイルの拡張が欲しい。これを自分で実装するのは簡単です。

public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
   foreach (var x in @this)
      action(x);
}
3
dustyburwell

標準のLinqにはそのようなことは何もありませんが、 MoreLinq にはForEach演算子があります。