call a function for each value in a generic c# collection

C#LinqLambdaGenerics

C# Problem Overview


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?

something like... myList.Where(p => myFunc(p.Value)); ?

thanks in advance, -s

C# Solutions


Solution 1 - C#

LINQ doesn't help here, but you can use List<T>.ForEach:

> List<T>.ForEach Method > > Performs the specified action on each element of the 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>.

Solution 2 - C#

As other posters have noted, you can use List<T>.ForEach.

However, you can easily write an extension method that allows you to use ForEach on any 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( ... );

Solution 3 - C#

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.

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:

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.

Second, Inside of the Select one Func<string> is going to be declared for each element of the given array as it called 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)

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.

Third, If you don't put the second Select then 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:

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.

Solution 4 - C#

You could use the List.ForEach method, as such:

myList.ForEach(p => myFunc(p));

Solution 5 - C#

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:

items.ForEach(item => DoSomething(item));

Solution 6 - C#

You can use the ForEach method:

MSDN:

http://msdn.microsoft.com/en-us/library/bwabdf9z.aspx

Solution 7 - C#

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 MoreLINQ written by Jon Skeet, et al.

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).

Solution 8 - C#

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);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStrattonView Question on Stackoverflow
Solution 1 - C#dtbView Answer on Stackoverflow
Solution 2 - C#Winston SmithView Answer on Stackoverflow
Solution 3 - C#KharazmiView Answer on Stackoverflow
Solution 4 - C#Matt HamsmithView Answer on Stackoverflow
Solution 5 - C#Neil BarnwellView Answer on Stackoverflow
Solution 6 - C#tsterView Answer on Stackoverflow
Solution 7 - C#Martin R-LView Answer on Stackoverflow
Solution 8 - C#granadaCoderView Answer on Stackoverflow