LINQ를 사용하여 다음 작업을 수행 할 수 있습니까?
foreach (var c in collection)
{
c.PropertyToSet = value;
}
명확히하기 위해 컬렉션의 각 객체를 반복하고 각 객체의 속성을 업데이트하려고합니다.
내 유스 케이스는 블로그 게시물에 대해 많은 의견을 갖고 있으며 블로그 게시물의 각 댓글을 반복하고 블로그 게시물의 날짜 시간을 +10 시간으로 설정하려고합니다. SQL로 할 수는 있지만 비즈니스 계층에 보관하고 싶습니다.
당신이 사용할 수있는 동안ForEach
확장 방법, 당신이 할 수있는 프레임 워크 만 사용하려면
collection.Select(c => {c.PropertyToSet = value; return c;}).ToList();
그만큼ToList
로 인해 즉시 선택을 평가하기 위해 필요합니다.게으른 평가.
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
-loop (이유가 무엇이든). - 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
다시 말하지만, 이것은 다른 누군가의 해결책입니다. 하지만이 코드를 작은 라이브러리로 컴파일하고 상당히 규칙적으로 사용합니다.
나는 그의 사이트 (블로그)가 미래의 어떤 시점에 존재하지 않게 될 가능성에 대비하여 코드를 여기에 붙여 넣을 것이다. ( "필요한 정확한 대답은 여기 있습니다", 클릭 및 죽은 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
아니요, LINQ는 대량 업데이트 방식을 지원하지 않습니다. 유일한더 짧은방법은ForEach
확장 메소드 -IEnumerable에 ForEach 확장 메서드가없는 이유는 무엇입니까?
내 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 - 솔루션을 요청했지만이 질문은 꽤 오래 전 non-linq 솔루션을 게시합니다. 이것은 linq (= lanuguage 통합질문)는 컬렉션에 대한 쿼리에 사용됩니다. 모든 linq 메서드는 기본 컬렉션을 수정하지 않습니다.반환새로운 컬렉션 (또는 새로운 컬렉션의 반복자) 따라서 무엇을 하든지. ~와Select
기본 컬렉션에 영향을 미치지 않으면 새 컬렉션을 얻으십시오.
물론 너.할 수 있었다그것으로해라.ForEach
(linq는 아니지만 그런데 확장 기능은List<T>
). 하지만 이것은말 그대로용도foreach
어쨌든 람다 표현식을 사용합니다. 이 외에도...마다linq-method는 내부적으로 컬렉션을 반복합니다. 사용하여foreach
또는for
그러나 클라이언트에서 단순히 숨 깁니다. 나는 이것을 더 이상 읽을 수없고 유지할 수 없다고 생각하지 않는다. (람다 표현식을 포함하는 메소드를 디버깅하는 동안 코드를 편집하는 것을 생각해 보라.)
이 shoulndt는 Linq를 사용하여수정하다컬렉션의 항목 더 나은 방법은 이미 질문에 제공 한 솔루션입니다. 클래식 루프를 사용하면 컬렉션을 쉽게 반복하고 항목을 업데이트 할 수 있습니다. 사실 이러한 모든 해결책은List.ForEach
내 관점에서 읽는 것이 다르지만 훨씬 더 어렵습니다.
그래서 당신이 원하는 경우 linq을 사용해서는 안됩니다.최신 정보컬렉션의 요소.
for
루프 "후드"아래에 위치한다. 나는 단순한 작업을하는 덜 장황한 방법을 만들기 위해 표준적인 코딩을 대신 할 수있는 합성 설탕이라고 생각한다. - ForeverZer0
LINQ를 사용하여 컬렉션을 배열로 변환 한 다음 Array.ForEach ()를 호출 할 수 있습니다.
Array.ForEach(MyCollection.ToArray(), item=>item.DoSomeStuff());
분명히 이것은 정수 또는 문자열과 같은 구조체 또는 inbuilt 형식의 컬렉션과 함께 작동하지 않습니다.
내가 사용하는 확장 방법은 다음과 같습니다.
/// <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; }
}
그러나 그것이 당신이 의미하는 것이면 shure하지 마라.