LINQを使用して次のことを行う方法はありますか?
foreach (var c in collection)
{
c.PropertyToSet = value;
}
わかりやすくするために、コレクション内の各オブジェクトを繰り返し処理してから、各オブジェクトのプロパティを更新します。
私のユースケースは、私がブログ記事にたくさんのコメントを持っているということです、そして、私はブログ記事のそれぞれのコメントを通して反復して、+10時間にブログ記事の日時を設定したいです。私はSQLでそれをすることができました、しかし私はビジネス層でそれを保ちたいです。
あなたが使用することができますがForEach
あなたができるフレームワークだけを使いたいのであれば、拡張メソッド
collection.Select(c => {c.PropertyToSet = value; return c;}).ToList();
のToList
すぐにselectを評価するために必要です。遅延評価。
ObservableCollection
たとえば、新しいリストを作成するのではなく、その場でアイテムを変更すると便利です。 - Cameron MacFarland
collection.ToList().ForEach(c => c.PropertyToSet = value);
collection.ToList().ForEach(c => { c.Property1ToSet = value1; c.Property2ToSet = value2; });
- Ε Г И І И О
私はこれをやっています
Collection.All(c => { c.needsChange = value; return true; });
All()
他の誰かがコードを読んだときに混乱を招く可能性がある拡張方法。 - Tom Baxter
私は実際に拡張メソッドを見つけましたそれは私がうまく欲しいことをするでしょう
public static IEnumerable<T> ForEach<T>(
this IEnumerable<T> source,
Action<T> act)
{
foreach (T element in source) act(element);
return source;
}
foreach
- ループ(なんらかの理由で) - Rangoforeach
コード自体にforeach
ループ - GoldBishop
つかいます:
ListOfStuff.Where(w => w.Thing == value).ToList().ForEach(f => f.OtherThing = vauleForNewOtherThing);
これがLINQを使いすぎているかどうかはわかりませんが、リスト内の特定の項目を特定の条件に合わせて更新したい場合に役立ちます。
これを行うための組み込みの拡張方法はありません。定義するのはかなり簡単ですが。記事の一番下に、私が定義したメソッドIterateがあります。こんな感じで使えます
collection.Iterate(c => { c.PropertyToSet = value;} );
ソースを繰り返す
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, (x, i) => callback(x));
}
public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
if (enumerable == null)
{
throw new ArgumentNullException("enumerable");
}
IterateHelper(enumerable, callback);
}
private static void IterateHelper<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
int count = 0;
foreach (var cur in enumerable)
{
callback(cur, count);
count++;
}
}
私はこれについていくつかのバリエーションを試しました、そして私はこの男の解決策に戻り続けます。
http://www.hookedonlinq.com/UpdateOperator.ashx
繰り返しますが、これは他の誰かの解決策です。しかし、私はコードを小さなライブラリにコンパイルし、そしてそれをかなり定期的に使用しています。
彼のサイト(ブログ)が将来のある時点で存在しなくなる可能性があるため、ここに彼のコードを貼り付けます。 (「ここにあなたが必要とする正確な答えがあります」と書かれた、クリックして、そしてDead URLと書かれた記事を見ることほど悪いことは何もない。)
public static class UpdateExtensions {
public delegate void Func<TArg0>(TArg0 element);
/// <summary>
/// Executes an Update statement block on all elements in an IEnumerable<T> sequence.
/// </summary>
/// <typeparam name="TSource">The source element type.</typeparam>
/// <param name="source">The source sequence.</param>
/// <param name="update">The update statement to execute for each element.</param>
/// <returns>The numer of records affected.</returns>
public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> update)
{
if (source == null) throw new ArgumentNullException("source");
if (update == null) throw new ArgumentNullException("update");
if (typeof(TSource).IsValueType)
throw new NotSupportedException("value type elements are not supported by update.");
int count = 0;
foreach (TSource element in source)
{
update(element);
count++;
}
return count;
}
}
int count = drawingObjects
.Where(d => d.IsSelected && d.Color == Colors.Blue)
.Update(e => { e.Color = Color.Red; e.Selected = false; } );
Action<TSource>
追加のデリゲートを作成する代わりに。しかし、それを書いている時点では利用できなかったかもしれません。 - Frank J
私の2ペニー: -
collection.Count(v => (v.PropertyToUpdate = newValue) == null);
私はそれを手助けするためにいくつかの拡張方法を書きました。
namespace System.Linq
{
/// <summary>
/// Class to hold extension methods to Linq.
/// </summary>
public static class LinqExtensions
{
/// <summary>
/// Changes all elements of IEnumerable by the change function
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="change">The way you want to change the stuff</param>
/// <returns>An IEnumerable with all changes applied</returns>
public static IEnumerable<T> Change<T>(this IEnumerable<T> enumerable, Func<T, T> change )
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
foreach (var item in enumerable)
{
yield return change(item);
}
}
/// <summary>
/// Changes all elements of IEnumerable by the change function, that fullfill the where function
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="change">The way you want to change the stuff</param>
/// <param name="where">The function to check where changes should be made</param>
/// <returns>
/// An IEnumerable with all changes applied
/// </returns>
public static IEnumerable<T> ChangeWhere<T>(this IEnumerable<T> enumerable,
Func<T, T> change,
Func<T, bool> @where)
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
ArgumentCheck.IsNullorWhiteSpace(@where, "where");
foreach (var item in enumerable)
{
if (@where(item))
{
yield return change(item);
}
else
{
yield return item;
}
}
}
/// <summary>
/// Changes all elements of IEnumerable by the change function that do not fullfill the except function
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="change">The way you want to change the stuff</param>
/// <param name="where">The function to check where changes should not be made</param>
/// <returns>
/// An IEnumerable with all changes applied
/// </returns>
public static IEnumerable<T> ChangeExcept<T>(this IEnumerable<T> enumerable,
Func<T, T> change,
Func<T, bool> @where)
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(change, "change");
ArgumentCheck.IsNullorWhiteSpace(@where, "where");
foreach (var item in enumerable)
{
if (!@where(item))
{
yield return change(item);
}
else
{
yield return item;
}
}
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="update">The way you want to change the stuff</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> Update<T>(this IEnumerable<T> enumerable,
Action<T> update) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
update(item);
}
return enumerable;
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// where the where function returns true
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="update">The way you want to change the stuff</param>
/// <param name="where">The function to check where updates should be made</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> UpdateWhere<T>(this IEnumerable<T> enumerable,
Action<T> update, Func<T, bool> where) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
if (where(item))
{
update(item);
}
}
return enumerable;
}
/// <summary>
/// Update all elements of IEnumerable by the update function (only works with reference types)
/// Except the elements from the where function
/// </summary>
/// <param name="enumerable">The enumerable where you want to change stuff</param>
/// <param name="update">The way you want to change the stuff</param>
/// <param name="where">The function to check where changes should not be made</param>
/// <returns>
/// The same enumerable you passed in
/// </returns>
public static IEnumerable<T> UpdateExcept<T>(this IEnumerable<T> enumerable,
Action<T> update, Func<T, bool> where) where T : class
{
ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
ArgumentCheck.IsNullorWhiteSpace(update, "update");
foreach (var item in enumerable)
{
if (!where(item))
{
update(item);
}
}
return enumerable;
}
}
}
私はこのように使っています:
List<int> exampleList = new List<int>()
{
1, 2 , 3
};
//2 , 3 , 4
var updated1 = exampleList.Change(x => x + 1);
//10, 2, 3
var updated2 = exampleList
.ChangeWhere( changeItem => changeItem * 10, // change you want to make
conditionItem => conditionItem < 2); // where you want to make the change
//1, 0, 0
var updated3 = exampleList
.ChangeExcept(changeItem => 0, //Change elements to 0
conditionItem => conditionItem == 1); //everywhere but where element is 1
参考のために引数チェック
/// <summary>
/// Class for doing argument checks
/// </summary>
public static class ArgumentCheck
{
/// <summary>
/// Checks if a value is string or any other object if it is string
/// it checks for nullorwhitespace otherwhise it checks for null only
/// </summary>
/// <typeparam name="T">Type of the item you want to check</typeparam>
/// <param name="item">The item you want to check</param>
/// <param name="nameOfTheArgument">Name of the argument</param>
public static void IsNullorWhiteSpace<T>(T item, string nameOfTheArgument = "")
{
Type type = typeof(T);
if (type == typeof(string) ||
type == typeof(String))
{
if (string.IsNullOrWhiteSpace(item as string))
{
throw new ArgumentException(nameOfTheArgument + " is null or Whitespace");
}
}
else
{
if (item == null)
{
throw new ArgumentException(nameOfTheArgument + " is null");
}
}
}
}
あなたは特にlinq-solutionを求めていて、この質問はかなり古いですが、私はnon-linq-solutionを投稿しています。これはlinq(= lanuguageが統合されているためです問い合わせ)コレクションに対する問い合わせに使用されるべきです。すべてのlinqメソッドは、基礎となるコレクションを修正しません。戻る新しいもの(より正確には新しいコレクションへのイテレータ)したがって、あなたがすることは何でも。とともにSelect
基礎となるコレクションには影響しません。単に新しいコレクションを入手するだけです。
もちろんあなたできたでそれを行うForEach
(ところで、これはlinqではありませんが、拡張子はList<T>
)でも、これ文字通り用途foreach
とにかくラムダ式ですが。これから離れてすべてのlinq-methodはコレクションを内部的に繰り返します。を使ってforeach
またはfor
しかし、それは単にクライアントからそれを隠します。これ以上読みやすく保守しやすいとは考えていません(ラムダ式を含むメソッドをデバッグしながらコードを編集することは考えないでください)。
この肩はLinqを使って修正するあなたのコレクションの中のアイテム。もっと良い方法はあなたがすでにあなたの質問で提供した解決策です。古典的なループを使用すると、コレクションを簡単に繰り返してそのアイテムを更新できます。実際には、これらすべての解決策に頼っていますList.ForEach
何も変わらないが、私の観点から読むのははるかに難しい。
だからあなたがしたい場合にはlinqを使うべきではない更新あなたのコレクションの要素
for
「フードの下に」ループします。標準的なコーディングに代わるものではなく、単純なタスクを実行するための冗長度の低い方法を作成することは構文上の砂糖だと思います。 - ForeverZer0
LINQを使用してコレクションを配列に変換してからArray.ForEach()を呼び出すことができます。
Array.ForEach(MyCollection.ToArray(), item=>item.DoSomeStuff());
明らかにこれは構造体のコレクションや整数や文字列のような作り付けの型では動作しません。
これが私が使っている拡張方法です。
/// <summary>
/// Executes an Update statement block on all elements in an IEnumerable of T
/// sequence.
/// </summary>
/// <typeparam name="TSource">The source element type.</typeparam>
/// <param name="source">The source sequence.</param>
/// <param name="action">The action method to execute for each element.</param>
/// <returns>The number of records affected.</returns>
public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
if (typeof (TSource).IsValueType)
throw new NotSupportedException("value type elements are not supported by update.");
var count = 0;
foreach (var element in source)
{
action(element);
count++;
}
return count;
}
List<T>.ForEach
また、すべての人のためにIEnumerable
。 - HimBromBeere
私はあなたがそれのために関数を書くことができるようにあなたが質問の中で値を変えたいと思う
void DoStuff()
{
Func<string, Foo, bool> test = (y, x) => { x.Bar = y; return true; };
List<Foo> mylist = new List<Foo>();
var v = from x in mylist
where test("value", x)
select x;
}
class Foo
{
string Bar { get; set; }
}
しかし、これがあなたが意味するものであるかどうか恥ずかしがらないでください。