为通用 c# 集合中的每个值调用一个函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1883920/
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
call a function for each value in a generic c# collection
提问by Stratton
I have a collection of integer values in a List collection. I want to call a function for each value in the collection where one of the function's argument is a collection value. Without doing this in a foreach loop... is there a way to accomplish this with a lambda/linq expression?
我在 List 集合中有一个整数值集合。我想为集合中的每个值调用一个函数,其中函数的参数之一是集合值。如果不在 foreach 循环中执行此操作...有没有办法使用 lambda/linq 表达式来完成此操作?
something like... myList.Where(p => myFunc(p.Value));
?
像…… myList.Where(p => myFunc(p.Value));
?
thanks in advance, -s
提前致谢,-s
回答by tster
You can use the ForEach method:
您可以使用 ForEach 方法:
MSDN:
微软:
回答by dtb
LINQ doesn't help here, but you can use List<T>.ForEach
:
LINQ 在这里没有帮助,但您可以使用List<T>.ForEach
:
List<T>.ForEach Method
Performs the specified action on each element of the List.
List<T>.ForEach 方法
对 List 的每个元素执行指定的操作。
Example:
例子:
myList.ForEach(p => myFunc(p));
The value passed to the lambda expression is the list item, so in this example p
is a long
if myList
is a List<long>
.
传递给 lambda 表达式的值是列表项,所以在这个例子中p
是 a long
if myList
is a List<long>
。
回答by Matt Hamsmith
You could use the List.ForEach method, as such:
您可以使用 List.ForEach 方法,如下所示:
myList.ForEach(p => myFunc(p));
回答by Neil Barnwell
No - if you want to call a function for each item in a list, you have to call the function for each item in the list.
否 - 如果您想为列表中的每个项目调用一个函数,则必须为列表中的每个项目调用该函数。
However, you can use the IList<T>.ForEach()
method as a bit of syntactic sugar to make the "business end" of the code more readable, like so:
但是,您可以将该IList<T>.ForEach()
方法用作一些语法糖来使代码的“业务端”更具可读性,如下所示:
items.ForEach(item => DoSomething(item));
回答by Martin R-L
If you don't wan't to use the ForEach method of List<T>
, but rather use IEnumerable<T>
(as one often does when "LINQ:ing"), I suggest MoreLINQwritten by Jon Skeet, et al.
如果您不想使用 的 ForEach 方法List<T>
,而是使用IEnumerable<T>
(就像“LINQ:ing”时经常做的那样),我建议使用由 Jon Skeet 等人编写的MoreLINQ。
MoreLINQ will give you ForEach, and also Pipe (and a bunch of other methods), which performs an action on each element, but returns the same IEnumerable<T>
(compared to void).
MoreLINQ 将为您提供 ForEach 和 Pipe(以及一堆其他方法),它们对每个元素执行一个操作,但返回相同的IEnumerable<T>
(与 void 相比)。
回答by Winston Smith
As other posters have noted, you can use List<T>.ForEach
.
正如其他海报所指出的,您可以使用List<T>.ForEach
.
However, you can easily write an extension method that allows you to use ForEach on any IEnumerable<T>
但是,您可以轻松编写一个扩展方法,允许您在任何 IEnumerable<T>
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach(T item in source)
action(item);
}
Which means you can now do:
这意味着您现在可以执行以下操作:
myList.Where( ... ).ForEach( ... );
回答by granadaCoder
Here is a mini (yet complete) example.
这是一个迷你(但完整)的示例。
public class Employee
{
public string EmployeeNumber { get; set; }
public DateTime? HireDate { get; set; }
}
public class EmployeeCollection : List<Employee>
{ }
private void RunTest()
{
EmployeeCollection empcoll = new EmployeeCollection();
empcoll.Add(new Employee() { EmployeeNumber = "1111", HireDate = DateTime.Now });
empcoll.Add(new Employee() { EmployeeNumber = "3333", HireDate = DateTime.Now });
empcoll.Add(new Employee() { EmployeeNumber = "2222", HireDate = null });
empcoll.Add(new Employee() { EmployeeNumber = "4444", HireDate = null });
//Here's the "money" line!
empcoll.Where(x => x.HireDate.HasValue == false).ToList().ForEach(item => ReportEmployeeWithMissingHireDate(item.EmployeeNumber));
}
private void ReportEmployeeWithMissingHireDate(string employeeNumber)
{
Console.WriteLine("We need to find a HireDate for '{0}'!", employeeNumber);
}
回答by Kharazmi
Yap! You can use List.ForEach
but the problem is that works only for list (For sure you can change everything to a List on the fly, but less code more fun :)). Beside, you have to use Action<>
prediction that does not provide any return type.
耶!您可以使用,List.ForEach
但问题是仅适用于列表(当然,您可以将所有内容即时更改为列表,但更少的代码更有趣:))。此外,您必须使用Action<>
不提供任何返回类型的预测。
Anyway there is an answer for what you wanted, you can make it possible in the same way you guessed with Func<>
but with a tiny trick as below:
无论如何,您想要的答案都有,您可以按照您猜测的方式实现,Func<>
但有一个小技巧,如下所示:
I will do everything here on the fly:
我将在这里即时完成所有操作:
string[] items = (new string[] { "d", "f" }).
Select(x => new Func<string>(() => {
//Do something here...
Console.WriteLine(x);
return x.ToUpper();
}
)).Select(t => t.Invoke()).ToArray<string>();
There are some points here:
这里有几点:
First, I have defined a string array on the fly that can be replaced by any collection that supports LINQ.
首先,我动态定义了一个字符串数组,它可以被任何支持 LINQ 的集合替换。
Second, Inside of the Select
one Func<string>
is going to be declared for each element of the given array as it called x
.
其次,Inside of the Select
oneFunc<string>
将在调用时为给定数组的每个元素声明x
。
(Look at the empty parenthesis and remember that when you define a Func<type**1**, type**2**, ..., type**n**>
always the last type is the return type, so when you write just Func<string>
it indicates a function that has no input parameter and its return type is string)
(看空括号,记住当你定义 a Func<type**1**, type**2**, ..., type**n**>
always 时,最后一个类型是返回类型,所以当你写 just Func<string>
it 表示一个没有输入参数的函数,它的返回类型是 string)
It is clear that we want to use the function over the given array (new string[] { "d", "f" })
, and that's why I define a function with no parameter and also I have used same variable x
inside of Func<>
to refer to the same array elements.
很明显,我们想在给定的数组上使用该函数(new string[] { "d", "f" })
,这就是为什么我定义了一个没有参数的函数,并且我在x
里面使用了相同的变量Func<>
来引用相同的数组元素。
Third, If you don't put the second Selectthen you have a collection of two functions that return string, and already they've got their inputs from the first array. You can do this and keep the result in an anonymous
variable and then call their .Invoke
methods. I write it here:
第三,如果您不放置第二个 Select那么您将拥有两个返回字符串的函数的集合,并且它们已经从第一个数组中获得了输入。您可以这样做并将结果保存在anonymous
变量中,然后调用它们的.Invoke
方法。我在这里写:
var functions = (new string[] { "d", "f" }).
Select(x => new Func<string>(() => {
//Do something here...
Console.WriteLine(x);
return x.ToUpper();
}));
string[] items = functions.Select(t => t.Invoke()).ToArray<string>();
Finally, I've converted the result to an array! Now you have a string array!
最后,我已将结果转换为数组!现在你有了一个字符串数组!
Sorry It get long!! I hope it would be useful.
对不起它变长了!!我希望它会很有用。