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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/823532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:02:23  来源:igfitidea点击:

Apply function to all elements of collection through LINQ

c#.netlinq

提问by Midhat

I have recently started off with LINQ and its amazing. I was wondering if LINQ would allow me to apply a function - any function - to all the elements of a collection, without using foreach. Something like python lambda functions.

我最近开始使用 LINQ,它很棒。我想知道 LINQ 是否允许我在不使用 foreach 的情况下将函数(任何函数)应用于集合的所有元素。类似于 python lambda 函数的东西。

For example if I have a int list, Can I add a constant to every element using LINQ

例如,如果我有一个 int 列表,我可以使用 LINQ 向每个元素添加一个常量吗

If i have a DB table, can i set a field for all records using LINQ.

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

I am using C#

我正在使用 C#

采纳答案by Jon Skeet

A common way to approach this is to add your own ForEachgeneric method on IEnumerable<T>. Here's the one we've got in MoreLINQ:

解决此问题的常用方法是ForEachIEnumerable<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);
    }
}

(Where ThrowIfNullis an extension method on any reference type, which does the obvious thing.)

ThrowIfNull任何引用类型的扩展方法在哪里,这很明显。)

It'll be interesting to see if this is part of .NET 4.0. It goes against the functional style of LINQ, but there's no doubt that a lot of people find it useful.

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

Once you've got that, you can write things like:

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

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

回答by mqp

The idiomatic way to do this with LINQ is to process the collection and return a new collection mapped in the fashion you want. For example, to add a constant to every element, you'd want something like

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

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

Doing this in a functional way instead of mutating the state of your existing collection frequently helps you separate distinct operations in a way that's both easier to read and easier for the compiler to reason about.

以函数方式执行此操作而不是经常改变现有集合的状态,可以帮助您以更易于阅读且编译器更易于推理的方式分离不同的操作。

If you're in a situation where you actually want to apply an action to every element of a collection (an action with side effects that are unrelated to the actual contents of the collection) that's not really what LINQ is best suited for, although you could fake it with Select(or write your own IEnumerableextension method, as many people have.) It's probably best to stick with a foreachloop in that case.

如果您实际上希望将操作应用于集合的每个元素(具有与集合的实际内容无关的副作用的操作),那么这并不是 LINQ 最适合的方式,尽管您可以用Select(或IEnumerable像很多人一样编写自己的扩展方法)来伪造它。foreach在这种情况下最好坚持使用循环。

回答by andy

haha, man, I just asked this question a few hours ago (kind of)...try this:

哈哈,伙计,我几个小时前才问过这个问题(有点)……试试这个:

example:

例子:

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

ForEach()is one of the built in .NET methods

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

This will modify the list, as opposed to returning a new one.

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

回答by Drahcir

You can try something like

你可以尝试类似的东西

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

Returns a list of id's +1, you can do the same with using a function to whatever you have in the select clause.

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

Update: As suggested from Jon Skeet this is a better version of the snippet of code I just posted:

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

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

回答by Jaans

You could also consider going parallel, especially if you don't care about the sequence and more about getting something done for each item:

您也可以考虑并行,特别是如果您不关心顺序并且更关心为每个项目完成某事时:

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

For example:

例如:

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

HTH.

哈。

回答by user2500321

I found some way to perform in on dictionary contain my custom class methods

我找到了一些在字典中执行的方法包含我的自定义类方法

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

Where 'this' derived from : Dictionary<string, MyCustomClass>

其中“this”源自:Dictionary<string, MyCustomClass>

class MyCustomClass 
{
   public void Refresh(){}
}

回答by zmechanic

For collections that do not support ForEachyou can use static ForEachmethod in Parallelclass:

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

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

回答by Hyman_2060

Or you can hack it up.

或者你可以破解它。

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