C# Code Simplification Query: The Sequential Foreach Loops - c#

Suppose I have some code that looks like this:
foreach(type x in list y)
{
//dostuff1(x)
}
foreach(type x in list y)
{
//dostuff2(x)
}
foreach(type x in list y)
{
//dostuff3(x)
}
foreach(type x in list y)
{
//dostuff4(x)
}
foreach(type x in list y)
{
//dostuff5(x)
}
I cannot combine things into one big for loop like this:
foreach (type x in list y)
{
//dostuff1(x)
//dostuff2(x)
//dostuff3(x)
//dostuff4(x)
//dostuff5(x)
}
Doing so would change the order. Any commentary on the best ways to make the code simpler in C#?
I imagine I could solve this problem by creating a function like this, though I'd rather leave it the way it is than force future readers of my code to understand yield:
void func(type x)
{
dostuff1(x)
yield 0;
dostuff2(x)
yield 0;
dostuff3(x)
yield 0;
dostuff4(x)
yield 0;
dostuff5(x)
yield break;
}
for (int i = 0; i<5; ++i)
{
foreach (type x in list y)
{
//Call func(x) using yield semantics, which I'm not going to look up right now
}
}

Another alternative:
List<Action<Foo>> actions = new List<Action<Foo>> {
doStuff1, doStuff2, doStuff3, doStuff4, doStuff5
};
foreach (Action<Foo> action in actions)
{
foreach (Foo x in list)
{
action(x);
}
}
Just checked, and that works. For instance:
using System;
using System.Collections.Generic;
public class Test
{
static void Main(string[] args)
{
var actions = new List<Action<string>> {
First, Second
};
foreach (var action in actions)
{
foreach (string arg in args)
{
action(arg);
}
}
}
static void First(string x)
{
Console.WriteLine("First: " + x);
}
static void Second(string x)
{
Console.WriteLine("Second: " + x);
}
}
Results of running Test.exe a b c
First: a
First: b
First: c
Second: a
Second: b
Second: c

If you have a fairly constant list of actions, you could just avoid the foreach loops, but still do the actions explicitly (haven't tested the code):
list.ForEach(action1);
list.ForEach(action2);
list.ForEach(action3);
list.ForEach(action4);

Jon Skeet's answer is excellent (I just voted it up). Here's an idea to take it one step further:
If you do this a lot, you could make an extension method called "DoActionsInOrder" (or maybe you can come up with a better name) that does this. Here's the idea:
public static void DoActionsInOrder<T>(this IEnumerable<T> stream, params Action<T> actionList)
{
foreach(var action in actionList)
{
foreach(var item in stream)
{
action(item);
}
}
}
Then, you could call it like this:
myList.DoActionsInOrder(doStuff1, doStuff2, doStuff3, doStuff4, doStuff5);

How about:
interface IDoStuff
{
void DoStuff(x);
}
List<IDoStuff> listOfActions = ...
foreach (IDoStuff iDoStuff in listOfActions)
{
foreach (type x in list y)
{
iDoStuff(x);
}
}
[edit] And yes, you should rather go for the generic solution as J.Skeet said (although you can use a generic interface instead of a delegate as well).

If you must retain the sequential nature, there's not much you can do. You could do some extension method shortcuts, but IMHO this makes for less readable code. Also, you may run into problems depending on your method signatures.
You could refactor to move the iteration to separate functions.
// Method 1
DoStuff1ToList(y);
DoStuff2ToList(y);
DoStuff3ToList(y);
DoStuff4ToList(y);
DoStuff5ToList(y);
// Do Stuff 1
foreach (var x in y)
{
// do actual stuff
}

i think this is the same as testing.ForEach(action)
so just use that if your going down this kind of route.
private static void DoDifferentStuffToThings()
{
List<string> testing = new List<string>() { "hello", "world" };
Action<string> action1 = (a) =>
{
Console.WriteLine("Action 1 {0}", a);
};
Action<string> action2 = (a) =>
{
Console.WriteLine("Action 2 {0}", a);
};
DoStuffToThings<string>(testing, action1);
DoStuffToThings<string>(testing, action2);
}
private static void DoStuffToThings<T>(IEnumerable<T> list, Action<T> dothing)
where T : class
{
foreach (var item in list)
{
dothing(item);
}
}

Related

issues customizing List<T> into ListCustomMinIndexedForEach<T> (stripped from irelevant implementations)

I tried to do my best to keep the title short but still informative.
I think I have succeeded with most of it
my problem For Now:(TLDR below)
I could not succeed implementing a public void method-member, nor an extension to Implement custom ForEach() with index..
as Extension
public static ListWithCounter<T> ForEach<T>(this ListWithCounter<T> Self, Action<T> itm)//, ListWithCounter<T> l = l.CurId)
{
for (int i = 0; i < Self.Count; i++)
{
Self.CurId = i;
itm(Self[i]);Self.CurId++;
}
return Self;
}
this is a small issue I guess, the objectives :
Create Customized List No Fancy Extra(Expensive) methods
add an elegant ForEach implementation
optional tricks like out of the box GetEnumValues/names . To{ourCustomList}()
USAGE
in this example I am using an Enum ( names of Actions also used to present action items in console menu)
public enum ActSrptS { CreateMmfTfomFile_DoFormat, OpenExitMmfT, .... }
so I print it to console by unleashing the power of That small List class
//a struct ConsoleModifiers + ConsoleKey
ActScrptS aAction = ActScrptS._Start; Combination Comb = new Combination();
var actS = aAction._EnmGetValues();
var actSNms = aAction.EnumGetNamesToList().ForEach(Act =>
{
Console.WriteLine("[{0}]{1}", actS.CurId, Act);
});
Console.WriteLine("===============\r\n");
Console.WriteLine("please Select Action");
and it's simply using (TRYING without success for now..)
public static ListWithCounter<string> EnumGetNamesToList(this Enum selfEnum)
{
return selfEnum.GetType().GetFields(BindingFlags.Static | BindingFlags.Public)
.Select(f=>f.Name).ToList();
//var values = Enum.GetNames(typeof(selfEnum)).ToList();
//return values;
//var values = Enum.GetValues(typeof(Environment.SpecialFolder)).Cast<Environment.SpecialFolder>().ToList();
}
public static ListWithCounter<Enum> _EnmGetValues(this Enum Self)
{
ListWithCounter<Enum> enumerations = new ListWithCounter<Enum>();
foreach (FieldInfo fieldInfo in Self.GetType().GetFields(
BindingFlags.Static | BindingFlags.Public))
{
enumerations.Add((Enum)fieldInfo.GetValue(Self));
}
return enumerations;
}
so I started with MSDN List.cs
and I tried to implement as less methods as possible
leaving minimal important functionality
altering Growth/Expand for -minimal copying so staring capacity is from say 10-50, multiplied by *4 on each limit...
came out with this CODE
well I came up with this aventually
var actS = aActionCur._EnmGetValues().GetAsActionList();
actS.ForEach(act => Console.WriteLine("action [{0}] {1}", actS.CurId, act));
//which is using....v
public static ListWithCounter<Enum> _EnmGetValues(this Enum Self)
{
ListWithCounter<Enum> enumerations = new ListWithCounter<Enum>();
foreach (FieldInfo fieldInfo in Self.GetType().GetFields(
BindingFlags.Static | BindingFlags.Public))
{
enumerations.Add((Enum)fieldInfo.GetValue(Self));
}
return enumerations;
}
//which is using....v
public static ListWithCounter<T> ForEach<T>(this ListWithCounter<T> Self, Action<T> itm)
{
for (int i = 0; i < Self.Count; i++)
{
itm(Self[i]); Self.CurId++;
}
return Self;
}
end even better
public static ListWithCounter<ConsoleColor> GetAsConColors(this ListWithCounter<Enum> self)
{
return self[0].GetType().GetEnumValues().Cast<ConsoleColor>().ToList();
}
[1] Red
[2] blue ...
....
.....
catch user key and u have a one line console menu
Why not use some nice LINQ?
public class Program
{
public enum ActSrptS { CreateMmfTfomFile_DoFormat, OpenExitMmfT }
private static void Main()
{
var action = ActSrptS.OpenExitMmfT;
Enum.GetValues(action.GetType())
.OfType<ActSrptS>()
.Select((v, i) => $"[{i + 1}] {v}")
.ToList()
.ForEach(Console.WriteLine);
Console.WriteLine("===============\r\n");
Console.WriteLine("Please select Action");
}
}

How can I prevent duplication of a common loop in my solution?

I have this loop based on a jagged array below which I will need to use more than once at different places.
How can I prevent myself to rewrite this loop again and again so that I will duplicate it?
foreach (int[] columns in rowsAndColumns)
{
foreach (int element in columns)
{
}
}
You can write
foreach (int element in rowsAndColumns.SelectMany(col => col))
{
// ...
}
instead. If you don’t like to have to type that all the time, you can abstract it into a helper method:
foreach (int element in rowsAndColumns.Flatten())
{
// ...
}
// [...]
public IEnumerable<T> Flatten(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(e => e);
}
It depends on what you want to do, but if you want to perform an action on each int, you could go for something like the extension below. Some null checking might be advisible.
static class RowColExtension
{
public static void Each(this int[][] rowCols, Action<int> a)
{
foreach (var r in rowCols)
{
foreach (var c in r)
{
a(c);
}
}
}
}
It depends on what you want to do in the loop. I would approach it like this (untested code out of my head!):
public static class MyHelper {
public static void ForEach(this IEnumerable<int[]> rowsAndColumns, Action<int> action) {
foreach (int[] columns in rowsAndColumns) {
foreach (int element in columns) {
action(element);
}
}
}
}
Now you can call it like this:
rowsAndColumns.ForEach(e => Console.WriteLine(e));
Extension method:
// It's late and I'm tired, the array declaration might be off.
public static void Visit(this int[][] array, Action<int> visitor)
{
foreach (int[] columns in array)
{
foreach (int element in columns)
{
visitor(element);
}
}
}
myArray.Visit(elem => Console.WriteLine(elem));
You can use Action<int,int> to get the row too.
Since you are iterating over all elements without regard to the row or column you should turn your jagged array into a first class data structure and implement IEnumerable to iterate over the collection using foreach. The same first-class data structure can support one-argument and two-argument indexers, range checking, etc.
Edit:
Here is one approach to use abstraction instead of manipulating low-level data structures. This assumes the jagged array was allocated elsewhere. Either way, the point is we can now use foreach directly on the data structure:
public class JaggedArray : IEnumerable<int>
{
private int[][] array;
public JaggedArray(int[][] array)
{
this.array = array;
}
public int this[int row, int column]
{
get { return array[row][column]; }
set { array[row][column] = value; }
}
public IEnumerable<int[]> Rows
{
get { return array; }
}
public IEnumerator<int> GetEnumerator()
{
foreach (var row in array)
foreach (var item in row)
yield return item;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

C# is there a foreach oneliner available?

I just want to know if there is a foreach oneliner in C#, like the if oneliner (exp) ? then : else.
If you're dealing with an array then you can use the built-in static ForEach method:
Array.ForEach(yourArray, x => Console.WriteLine(x));
If you're dealing with a List<T> then you can use the built-in ForEach instance method:
yourList.ForEach(x => Console.WriteLine(x));
There's nothing built-in that'll work against any arbitrary IEnumerable<T> sequence, but it's easy enough to roll your own extension method if you feel that you need it:
yourSequence.ForEach(x => Console.WriteLine(x));
// ...
public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
foreach (T item in source)
{
action(item);
}
}
}
List.ForEach Method
Imagine you have three variables and you want to set the same property of them all in only one go:
foreach (var item in new [] {labelA, labelB, labelC})
{
item.Property= Value;
}
It is the equivalent of doing:
foreach (var item in new List<SomeType>(){labelA, labelB, labelC})
{
item.Property= Value;
}
foreach line-liners could be achieved with LINQ extension methods. For example:
instead of:
var result = new List<string>();
foreach (var item in someCollection)
{
result.Add(item.Title);
}
you could:
var result = someCollection.Select(x => x.Title).ToList();
Sure, you can use something like List<>.ForEach:
List<String> s = new List<string>();
s.Add("This");
s.Add("Is");
s.Add("Some");
s.Add("Data");
s.ForEach(_string => Console.WriteLine(_string));
The primary difference between if and the ?operator is that if is a statement, while ? produces an expression. I.e. you can do this:
var _ = (exp) ? then : else; // ok
but not this:
var _ = if (exp) { then; } else { else; }; // error
So if you are looking for something like a foreach expression, there is no .NET type that can naturally return except for void, but there are no values of void type, so you can equally just write:
foreach (var item in collection) process(item);
In many functional languages, a Unit type is used instead of void which is a type with only one value. You can emulate this in .NET and create your own foreach expression:
class Unit
{
public override bool Equals(object obj)
{
return true;
}
public override int GetHashCode()
{
return 0;
}
}
public static class EnumerableEx
{
public static Unit ForEach<TSource>(
this IEnumerable<TSource> source,
Action<TSource> action)
{
foreach (var item in source)
{
action(item);
}
return new Unit();
}
}
However there hardly exists any use-case for such expressions.

In C# 3.0 is there any syntax for a block of code that will run only if a foreach doesn't have any iterations?

meaning something like...
foreach(blah b in blahblahs)
{
writeOnMoon(b.name);
}
default
{
writeOnMoon("No Blahs!");
}
default or, otherwise, or something like that, if this does not exist... do you think it should?
how about:
bool run = false;
foreach (var item in collection)
{
run = true;
// Do stuff
}
if (!run)
{
// Other Stuff
}
There isn't a keyword to do this.
You can do:
if (blahblahs.Any())
{
foreach(blah b in blahblahs)
{
writeOnMoon(b.name);
}
}
else
{
writeOnMoon("No Blahs!");
}
Couldn't you just check blahblahs.length first?
This doesn't exist.
I don't think this should be in the language because it really doesn't allow you to do anything new, nor does it make any current complex tasks much simpler.
No, but you could write an extension method so you could write:
collection.ForEachOrDefault(b =>
{
WriteOnMoon(b.name);
}, () =>
{
WriteOnMoon("No Blahs!");
});
Admittedly I don't think I'd recommend it... but here's the code:
public static void ForEachOrDefault<T>(this IEnumerable<T> source,
Action<T> forEachAction, Action defaultAction)
{
// Nullity checking omitted for brevity
bool gotAny = false;
foreach (T t in source)
{
gotAny = true;
forEachAction(t);
}
if (!gotAny)
{
defaultAction();
}
}
No, there is not.
Nope, there's no specific syntax in C# that will do what you want.
You're forced to devise your own approach (like what JDunkerley's example shows).
Python has this (for ... else ...) and I really miss it in C#.
With LINQ you can do something like this:
public static IEnumerable<T> IfEmpty<T>(this IEnumerable<T> source, Action action)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
do yield return enumerator.Current; while (enumerator.MoveNext());
else
action();
}
mylistofobjects.Each(...).IfEmpty(() => { /* empty list */ });
No. But you can try to invent a simple extension method - for simple cases it will do...
public static class EnumerableExtension
{
public static void IfEmpty<T>(this IEnumerable<T> list, Action<IEnumerable<T>> action)
{
if (list.Count() == 0)
action(list);
}
}
foreach (var v in blabla)
{
}
blabla.IfEmpty(x => log("List is empty"));
Maybe you'll even be able to create re-usable actions then. Though it doesn't really make much sense.
IEnumerable myCollection = GetCollection();
if(myCollection.Any())
{
foreach(var item in myCollection)
{
//Do something
}
}
else
{
// Do something else
}

C# Syntax - Example of a Lambda Expression - ForEach() over Generic List

First, I know there are methods off of the generic List<> class already in the framework do iterate over the List<>.
But as an example, what is the correct syntax to write a ForEach method to iterate over each object of a List<>, and do a Console.WriteLine(object.ToString()) on each object.
Something that takes the List<> as the first argument and the lambda expression as the second argument.
Most of the examples I have seen are done as extension methods or involve LINQ. I'm looking for a plain-old method example.
public void Each<T>(IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
action(item);
}
... and call it thusly:
Each(myList, i => Console.WriteLine(i));
Is this what you're asking for?
int[] numbers = { 1, 2, 3 };
numbers.ToList().ForEach(n => Console.WriteLine(n));
The above could also be written with less code as:
new List<SomeType>(items).ForEach(
i => Console.WriteLine(i)
);
This creates a generic list and populates it with the IEnumerable and then calls the list objects ForEach.
public static void Each<T>(this IEnumerable<T> items, Action<T> action) {
foreach (var item in items) {
action(item);
} }
... and call it thusly:
myList.Each(x => { x.Enabled = false; });
Want to put out there that there is not much to worry about if someone provides an answer as an extension method because an extension method is just a cool way to call an instance method. I understand that you want the answer without using an extension method. Regardless if the method is defined as static, instance or extension - the result is the same.
The code below uses the code from the accepted answer to define an extension method and an instance method and creates a unit test to show the output is the same.
public static class Extensions
{
public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}
}
[TestFixture]
public class ForEachTests
{
public void Each<T>(IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}
private string _extensionOutput;
private void SaveExtensionOutput(string value)
{
_extensionOutput += value;
}
private string _instanceOutput;
private void SaveInstanceOutput(string value)
{
_instanceOutput += value;
}
[Test]
public void Test1()
{
string[] teams = new string[] {"cowboys", "falcons", "browns", "chargers", "rams", "seahawks", "lions", "heat", "blackhawks", "penguins", "pirates"};
Each(teams, SaveInstanceOutput);
teams.Each(SaveExtensionOutput);
Assert.AreEqual(_extensionOutput, _instanceOutput);
}
}
Quite literally, the only thing you need to do to convert an extension method to an instance method is remove the static modifier and the first parameter of the method.
This method
public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}
becomes
public void Each<T>(Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}
You can traverse each string in the list and even you can search in the whole generic using a single statement this makes searching easier.
public static void main(string[] args)
{
List names = new List();
names.Add(“Saurabh”);
names.Add("Garima");
names.Add(“Vivek”);
names.Add(“Sandeep”);
string stringResult = names.Find( name => name.Equals(“Garima”));
}
Standard:
foreach (Item i in allItems)
{
i.FK_ItemStatus_CustomCodeID = itemStatuses.Where(
x => x.CustomCodeID == i.ItemStatus_CustomCodeID).FirstOrDefault();
}
Lambda:
allItems.ForEach(
i => i.FK_ItemStatus_CustomCodeID =
itemStatuses.Where(
x => x.CustomCodeID == i.ItemStatus_CustomCodeID).FirstOrDefault()
);

Categories