通过LINQ将函数应用于所有收集元素
我最近开始与LINQ和它的惊人。 我想知道LINQ是否允许我将一个函数(任何函数)应用到集合的所有元素,而不使用foreach。 像Python lambda函数。
例如,如果我有一个int列表,我可以添加一个常数使用LINQ每个元素
如果我有一个数据库表,我可以使用LINQ设置所有logging的字段。
我正在使用C#
解决这个问题的常用方法是在IEnumerable<T>
上添加自己的ForEach
generics方法。 这是我们在MoreLINQ中得到的一个:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) { source.ThrowIfNull("source"); action.ThrowIfNull("action"); foreach (T element in source) { action(element); } }
(其中ThrowIfNull
是任何引用types的扩展方法,这是显而易见的事情。)
看看这是否是.NET 4.0的一部分将是有趣的。 它违背了LINQ的function风格,但毫无疑问,很多人觉得它有用。
一旦你有了,你可以写下如下的东西:
people.Where(person => person.Age < 21) .ForEach(person => person.EjectFromBar());
用LINQ做这个的惯用方法是处理集合并返回一个以你想要的方式映射的新集合。 例如,为每个元素添加一个常量,你会想要类似的东西
var newNumbers = oldNumbers.Select(i => i + 8);
以一种function性的方式来做这件事,而不是频繁地改变现有集合的状态,这样可以帮助您以不同的方式区分不同的操作,使得编译器更容易阅读,也更容易编译。
如果您处于某种情况下,您实际上想要将操作应用于集合中的每个元素(具有与集合的实际内容无关的副作用的操作),但这并不是LINQ最适合的操作,尽pipe您可以用Select
来伪造它(或者像很多人那样编写自己的IEnumerable
扩展方法)。在这种情况下,最好使用foreach
循环。
你也可以考虑平行,特别是如果你不关心序列,更多的是为每个项目完成一些事情:
SomeIEnumerable<T>.AsParallel().ForAll( Action<T> / Delegate / Lambda )
例如:
var numbers = new[] { 1, 2, 3, 4, 5 }; numbers.AsParallel().ForAll( Console.WriteLine );
HTH。
哈哈,老兄,我刚刚几个小时前问过这个问题(种)…试试这个:
例:
someIntList.ForEach(i=>i+5);
ForEach()是内置的.NET方法之一
这将修改列表,而不是返回一个新的。
或者你可以破解它。
Items.All(p => {p.IsAwesome = true; return true;});
对于不支持ForEach
集合,可以在Parallel
类中使用静态的ForEach
方法:
var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 }; Parallel.ForEach(_your_collection_, options, x => x._Your_Method_());
你可以尝试类似的东西
var foo = (from fooItems in context.footable select fooItems.fooID + 1);
返回一个id为+1的列表,你可以在select子句中使用一个函数来做同样的事情。
更新:根据Jon Skeet的build议,这是我刚发布的代码片段的更好的版本:
var foo = context.footable.Select(foo => foo.fooID + 1);
我发现一些方法来执行字典中包含我的自定义类的方法
foreach (var item in this.Values.Where(p => p.IsActive == false)) item.Refresh();
where'this'派生自:Dictionary <string,MyCustomClass>
class MyCustomClass { public void Refresh(){} }