通过LINQ将函数应用于集合的所有元素

时间:2009-05-05 05:58:00

标签: c# .net linq

我最近开始使用LINQ并且令人惊叹。我想知道LINQ是否允许我将函数 - 任何函数 - 应用于集合的所有元素,而不使用foreach。类似python lambda函数的东西。

例如,如果我有一个int列表,我可以使用LINQ

为每个元素添加一个常量

如果我有一个数据库表,我可以使用LINQ为所有记录设置一个字段。

我正在使用C#

8 个答案:

答案 0 :(得分:134)

解决此问题的常用方法是在ForEach上添加您自己的IEnumerable<T>通用方法。这是我们在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是任何引用类型的扩展方法,这很明显。)

看看这是否是.NET 4.0的一部分会很有趣。它违背了LINQ的功能风格,但毫无疑问,很多人发现它很有用。

一旦你有了这个,你可以写下这样的东西:

people.Where(person => person.Age < 21)
      .ForEach(person => person.EjectFromBar());

答案 1 :(得分:85)

使用LINQ执行此操作的惯用方法是处理集合并返回以您想要的方式映射的新集合。例如,要为每个元素添加常量,您需要类似

的内容
var newNumbers = oldNumbers.Select(i => i + 8);

以功能方式执行此操作而不是改变现有集合的状态经常有助于您以一种既易于阅读又更易于编译器推理的方式分离不同的操作。

如果您实际上想要将一个动作应用于集合的每个元素(一个副作用与集合的实际内容无关的动作),那么LINQ最适合的不是,虽然您可以使用Select伪造它(或者编写自己的IEnumerable扩展方法,就像许多人一样。)在这种情况下,最好坚持使用foreach循环。

答案 2 :(得分:39)

你也可以考虑并行,特别是如果你不关心序列,更多的是关于为每个项目完成一些事情:

SomeIEnumerable<T>.AsParallel().ForAll( Action<T> / Delegate / Lambda )

例如:

var numbers = new[] { 1, 2, 3, 4, 5 };
numbers.AsParallel().ForAll( Console.WriteLine );

HTH。

答案 3 :(得分:30)

哈哈,伙计,我几个小时前就问了这个问题(有点)......试试这个:

示例:

someIntList.ForEach(i=>i+5);

ForEach()是内置的.NET方法之一

这将修改列表,而不是返回新列表。

答案 4 :(得分:12)

或者你可以破解它。

Items.All(p => { p.IsAwesome = true; return true; });

答案 5 :(得分:5)

对于不支持ForEach的集合,您可以在ForEach类中使用静态Parallel方法:

var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 };
Parallel.ForEach(_your_collection_, options, x => x._Your_Method_());

答案 6 :(得分:1)

您可以尝试类似

的内容
var foo = (from fooItems in context.footable select fooItems.fooID + 1);

返回id的+1列表,您可以使用函数执行与select子句中的任何操作相同的操作。

更新:正如Jon Skeet所建议的那样,这是我发布的代码片段的更好版本:

var foo = context.footable.Select(foo => foo.fooID + 1);

答案 7 :(得分:-1)

我发现在字典中执行某种方式包含我的自定义类方法

foreach (var item in this.Values.Where(p => p.IsActive == false))
            item.Refresh();

'this'派生自:Dictionary&lt; string,MyCustomClass&gt;

class MyCustomClass 
{
   public void Refresh(){}
}