Changing Foreach Order? - c#

Is there anyway to foreach through a list from the end to the beginning rather than the beginning to then end (preferably without reordering the list).

using System.Linq;
foreach(var item in source.Reverse())
{
...
}
Edit: There is one more step if you are dealing specifically with a List<T>. That class defines its own Reverse method whose signature is not the same as the Enumerable.Reverse extension method. In that case, you need to "lift" the variable reference to IEnumerable<T>:
using System.Linq;
foreach(var item in list.AsEnumerable().Reverse())
{
...
}

you could use a regular for loop, start at the end and decrement, instead of starting at the top and incrementing.
something like:
for(int i=foo.lenth; i != 0; i--)
{
do stuff
}

You probably don't want to do anything complicated, so I would suggest just using a for loop.
However, if it were somehow a requirement, you can certainly implement your own iterators for custom list iteration behavior.

It depends on what you mean by list.
List<T> ? No, unless you use Linq and it's Reverse() function.
Your custom collection? Easily, just implement IEnumerator like you
want.

Error checking ommitted for clarity. Use a custom implementation of IEnumerable and IEnumerator. This will avoid unnecessary copying.
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class ReversedEnumerator : IEnumerator<int>
{
List<int> v;
int index;
public ReversedEnumerator(List<int> v) {
this.v = v;
this.index = v.Count;
}
public int Current
{
get { return v[index]; }
}
public void Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get { return v[index]; }
}
public bool MoveNext()
{
return --index >= 0;
}
public void Reset()
{
index = this.v.Count;
}
}
class EnumeratorStub : IEnumerable<int>
{
List<int> v;
public EnumeratorStub(List<int> v)
{
this.v = v;
}
public IEnumerator<int> GetEnumerator()
{
return new ReversedEnumerator(v);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new ReversedEnumerator(v);
}
}
class Program
{
static EnumeratorStub Reverse(List<int> v)
{
return new EnumeratorStub(v);
}
static void Main(string[] args)
{
List<int> v = new List<int>();
v.Add(1);
v.Add(2);
v.Add(3);
foreach (int item in Reverse(v))
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
I would recommend to refactor the code sample to use generics. That way you could use this for any container type.

IList<String> strList = new IList<String>();
strList.Add("A");
strList.Add("B");
strList.Add("C");
for (int i = strList.Count-1; i>=0;i--)
{
Console.WriteLine(strList[i]);
}
not tried but should work.

not c# but you can do it too :-)
Dim a As New List(Of Integer)
a.Add(1)
a.Add(2)
a.Add(3)
For Each i In a.AsEnumerable.Reverse
Debug.Print(i)
Next

You can construct your list as a stack and then iterate over the stack:
Stack<char> stack = new Stack<char>();
//Add items...
foreach(var item in stack)
{
...
}

Related

Yield return and dynamic

Is possible to invoke a "IEnumerable/yield return" method when using dynamic?
I'm asking this because I'm getting the error below when I call the "Test(States1.GetNames())" method.
Error: "Additional information: 'object' does not contain a definition for 'GetEnumerator'"
using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
namespace YieldDemo
{
public class States1
{
public static IEnumerable<string> GetNames()
{
yield return "Alabama";
yield return "Alaska";
yield return "Arizona";
yield return "Arkansas";
yield return "California";
yield return "Others ...";
}
}
public class States2
{
private static readonly IList<string> _names;
static States2()
{
_names = new List<string>() {"Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California",
"Others ..." };
}
public static IList<string> GetNames()
{
return _names;
}
}
public class Program
{
static void Main()
{
Test(States2.GetNames());
Test(States1.GetNames());
Console.ReadLine();
}
public static void Test(dynamic state)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Iterate(state);
stopwatch.Stop();
Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
}
public static void Iterate(dynamic itemList)
{
var enumerator = itemList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
}
}
Thanks
The problem is that the iterator block implementation uses explicit interface implementation to implement IEnumerable<T>... and explicit interface implementation doesn't play nicely with dynamic typing in general. (You don't need to use iterator blocks to see that. See my article on Gotchas in Dynamic Typing for more details.)
You can iterate with foreach though:
public static void Iterate(dynamic itemList)
{
foreach (dynamic item in itemList)
{
Console.WriteLine(item);
}
}
This has the additional benefit that it will dispose of the iterator for you, which your previous code didn't do :)
Alternatively, you add overloads for Iterate to take IEnumerable or IEnumerable<T>, and let execution-time overload resolution within Test do the right thing (due to state being dynamic too).
It fails because the IEnumerable<string> class generated by your yield code explicitly implements its interfaces (including the GetEnumerator you're trying to use). You can call the method like this:
public static void Iterate(dynamic itemList)
{
var enumerator = ((IEnumerable)itemList).GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
Or, since you don't need dynamic for any reason I can see here, maybe just:
public static void Iterate(IEnumerable itemList)
{
var enumerator = itemList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
Or
public static void Iterate<T>(IEnumerable<T> itemList)

Linq optimisation within a foreach

I have been looking for a way of splitting a foreach loop into multiple parts and came across the following code:
foreach(var item in items.Skip(currentPage * itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
Would items.Skip(currentPage * itemsPerPage).Take(itemsPerPage) be processed in every iteration, or would it be processed once, and have a temporary result used with the foreach loop automatically by the compiler?
No, it would be processed once.
It's the same like:
public IEnumerable<Something> GetData() {
return someData;
}
foreach(var d in GetData()) {
//do something with [d]
}
The foreach construction is equivalent to:
IEnumerator enumerator = myCollection.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
object current = enumerator.Current;
Console.WriteLine(current);
}
}
finally
{
IDisposable e = enumerator as IDisposable;
if (e != null)
{
e.Dispose();
}
}
So, no, myCollection would be processed only once.
Update:
Please note that this depends on the implementation of the IEnumerator that the IEnumerable uses.
In this (evil) example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
namespace TestStack
{
class EvilEnumerator<T> : IEnumerator<T> {
private IEnumerable<T> enumerable;
private int index = -1;
public EvilEnumerator(IEnumerable<T> e)
{
enumerable = e;
}
#region IEnumerator<T> Membres
public T Current
{
get { return enumerable.ElementAt(index); }
}
#endregion
#region IDisposable Membres
public void Dispose()
{
}
#endregion
#region IEnumerator Membres
object IEnumerator.Current
{
get { return enumerable.ElementAt(index); }
}
public bool MoveNext()
{
index++;
if (index >= enumerable.Count())
return false;
return true;
}
public void Reset()
{
}
#endregion
}
class DemoEnumerable<T> : IEnumerable<T>
{
private IEnumerable<T> enumerable;
public DemoEnumerable(IEnumerable<T> e)
{
enumerable = e;
}
#region IEnumerable<T> Membres
public IEnumerator<T> GetEnumerator()
{
return new EvilEnumerator<T>(enumerable);
}
#endregion
#region IEnumerable Membres
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
class Program
{
static void Main(string[] args)
{
IEnumerable<int> numbers = Enumerable.Range(0,100);
DemoEnumerable<int> enumerable = new DemoEnumerable<int>(numbers);
foreach (var item in enumerable)
{
Console.WriteLine(item);
}
}
}
}
Each iteration over enumerable would evaluate numbers two times.
Question:
Would items.Skip(currentPage * itemsPerPage).Take(itemsPerPage) be
processed every iteration, or would it be processed once, and have a
temporary result used with the foreach loop automatically by the
compiler?
Answer:
It would be processed once, not every iteration. You can put the collection into a variable to make the foreach more readable. Illustrated below.
foreach(var item in items.Skip(currentPage * itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
vs.
List<MyClass> query = items.Skip(currentPage * itemsPerPage).Take(itemsPerPage).ToList();
foreach(var item in query)
{
//Do stuff
}
vs.
IEnumerable<MyClass> query = items.Skip(currentPage * itemsPerPage).Take(itemsPerPage);
foreach(var item in query)
{
//Do stuff
}
The code that you present will only iterate the items in the list once, as others have pointed out.
However, that only gives you the items for one page. If you are handling multiple pages, you must be calling that code once for each page (because somewhere you must be incrementing currentPage, right?).
What I mean is that you must be doing something like this:
for (int currentPage = 0; currentPage < numPages; ++currentPage)
{
foreach (var item in items.Skip(currentPage*itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
}
Now if you do that, then you will be iterating the sequence multiple times - once for each page. The first iteration will only go as far as the end of the first page, but the next will iterate from the beginning to the end of the second page (via the Skip() and the Take()) - and the next will iterate from the beginning to the end of the third page. And so on.
To avoid that you can write an extension method for IEnumerable<T> which partitions the data into batches (which you could also describe as "paginating" the data into "pages").
Rather than just presenting an IEnumerable of IEnumerables, it can be more useful to wrap each batch in a class to supply the batch index along with the items in the batch, like so:
public sealed class Batch<T>
{
public readonly int Index;
public readonly IEnumerable<T> Items;
public Batch(int index, IEnumerable<T> items)
{
Index = index;
Items = items;
}
}
public static class EnumerableExt
{
// Note: Not threadsafe, so not suitable for use with Parallel.Foreach() or IEnumerable.AsParallel()
public static IEnumerable<Batch<T>> Partition<T>(this IEnumerable<T> input, int batchSize)
{
var enumerator = input.GetEnumerator();
int index = 0;
while (enumerator.MoveNext())
yield return new Batch<T>(index++, nextBatch(enumerator, batchSize));
}
private static IEnumerable<T> nextBatch<T>(IEnumerator<T> enumerator, int blockSize)
{
do { yield return enumerator.Current; }
while (--blockSize > 0 && enumerator.MoveNext());
}
}
This extension method does not buffer the data, and it only iterates through it once.
Given this extension method, it becomes more readable to batch up the items. Note that this example enumerates through ALL items for all pages, unlike the OP's example which only iterates through the items for one page:
var items = Enumerable.Range(10, 50); // Pretend we have 50 items.
int itemsPerPage = 20;
foreach (var page in items.Partition(itemsPerPage))
{
Console.Write("Page " + page.Index + " items: ");
foreach (var i in page.Items)
Console.Write(i + " ");
Console.WriteLine();
}

C# IEnumerable, IEnumerator Reset Function Not Get Called

I'm basicly trying to make my class able to iterate using foreach. I read this tutorial. MSDN. It seems very straight forward. However, I have a problem when I want to iterate second time. I debugged it; and it turned out that it doesn't call the Reset() function.
Class A
class A : IEnumerable, IEnumerator
{
int[] data = { 0, 1, 2, 3, 4 };
int position = -1;
public object Current
{
get
{
return data[position];
}
}
public bool MoveNext()
{
position++;
return (position < data.Length);
}
public void Reset()
{
position = -1;
}
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
}
When I run the following main function; it never calls Reset() function. So, after one loop I never be able to iterate my class again.
Main
static void Main(string[] args)
{
A a = new A();
foreach (var item in a)
{
Console.WriteLine(item);
}
Console.WriteLine("--- First foreach finished. ---");
foreach (var item in a)
{
Console.WriteLine(item);
}
}
Output:
0
1
2
3
4
--- First foreach finished. ---
Press any key to continue . . .
Any thoughts?
Each time foreach is called, it asks for a new IEnumerator. Returning your class instance is a bad idea - you should make a separate class to implement the IEnumerator, and return it instead.
This is often done by using a nested (private) class, and returning an instance of it. You can pass the class A instance to the private class (giving it access to data), and put the position field in that class. It would allow more than one enumerator to be created simulatenously, and will work properly with subsequent foreach calls.
For example, to modify your code, you'd do something like:
using System;
using System.Collections;
class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
return new AEnumerator(this);
}
private class AEnumerator : IEnumerator
{
public AEnumerator(A inst)
{
this.instance = inst;
}
private A instance;
private int position = -1;
public object Current
{
get
{
return instance.data[position];
}
}
public bool MoveNext()
{
position++;
return (position < instance.data.Length);
}
public void Reset()
{
position = -1;
}
}
}
Note that you can also just return the array's enumerator directly (though I was assuming you were trying to learn how to make clean enumerators):
class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
return data.GetEnumerator();
}
}
Finally, you can use iterators to implement this in a far simpler manner:
class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
for (int i=0;i<data.Length;++i)
yield return data[i];
}
}
That being said, I would strongly recommend implementing IEnumerable<int> in addition to IEnumerable. Generics make this far nicer in terms of usage.
Reset() was basically a mistake. There's already a known method to get a clean enumerator if possible: GetEnumerator().
It is a requirement in the specification that iterator block implementations (for the iterator) throw an exception for this method, hence in the general case it is formally known that it can't be expected to work, and simply: nobody ever calls it. Frankly, they should also have marked it [Obsolete] on the API !
Additionally, many sequences are non-repeatable. Think of iterators sat on a NetworkStream or a random numer generator. Because iterators (in the general case) are not required to be repeatable, you should aim, where possible, to iterate them at most once. Perhaps buffering via ToList() if that is not possible.
"foreach" does not involve Reset() at any point. Just GetEnumerator(), MoveNext(), Current and Dispose().
The enumeration doesn't call Reset. You need to create a new instance of an enumerator, which will likely mean creating a separate class for the enumerator (i.e., not using the same type for the IEnumerable and IEnumerator), like in the code below:
public class StackOverflow_11475328
{
class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
return new AEnumerator(this);
}
class AEnumerator : IEnumerator
{
private A parent;
private int position = -1;
public AEnumerator(A parent)
{
this.parent = parent;
}
public object Current
{
get { return parent.data[position]; }
}
public bool MoveNext()
{
position++;
return (position < parent.data.Length);
}
public void Reset()
{
position = -1;
}
}
}
public static void Test()
{
A a = new A();
foreach (var item in a)
{
Console.WriteLine(item);
}
Console.WriteLine("--- First foreach finished. ---");
foreach (var item in a)
{
Console.WriteLine(item);
}
}
}
Both Reed and Carlos are correct. Here is one way you can do this, since int[] implements IEnumerable and IEnumerable<int>
class A : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
return data.GetEnumerator();
}
}
Or, to be more strongly typed, you can use the generic form of IEnumerable:
class A : IEnumerable<int>
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator<int> GetEnumerator()
{
return ((IEnumerable<int>)data).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return data.GetEnumerator();
}
}

What is the java Vector.element() C# equivalent

Here is the java code i incompletely tried to translate
static Enumeration enumerate()
{
Vector list = new Vector();
Enumeration e = cache.keys();
while (e.hasMoreElements())
{
Vector v = (Vector) cache.get(e.nextElement());
for (int i = 0; i < v.size(); i++)
{
list.addElement(v.elementAt(i));
}
}
return list.elements();
}
This is the C# translation but not complete
public static IEnumerable<Http> enumurate()
{
List<Http> list = new List<Http>();
IEnumerator e = cache.Keys.GetEnumerator();
while (e.MoveNext())/*While e has more element*/
{
var vector = (List<Http>)cache[e.Current];
for (int i = 0; i < vector.Count; i++)
{
list.Add(vector.ElementAt<Http>(i));
}
}
return //Something missing!!
}
Any help please !
In C# List<Http> implements IEnumerable<Http> so you can simply return your list:
return list;
To convert the code to C# even more, you could just skip the adding of elements to the list and yield results directly:
public static IEnumerable<Http> enumerate()
{
IEnumerator e = cache.Keys.GetEnumerator();
while (e.MoveNext())/*While e has more element*/
{
var vector = (List<Http>)cache[e.Current];
for (int i = 0; i < vector.Count; i++)
{
yield return vector.ElementAt<Http>(i);
}
}
}
Also, you can avoid using enumerators directly and make the code even more readable:
public static IEnumerable<Http> enumerate()
{
foreach (var key in cache.Keys)
{
foreach (var http in (List<Http>)cache[key])
{
yield return http;
}
}
}
Just return the local list. List<T> implements IEnumerable<T>.
In C# you can use LINQ to simplify your code:
public static IEnumerable<Http> enumerate()
{ return cache.Keys.SelectMany(key => (List<Http>)cache[key]); }
Assuming cache is declared as Dictionary<..., List<Http>> you can avoid key lookup by using the Values property:
public static IEnumerable<Http> enumerate()
{ return cache.Values.SelectMany(list => list); }
One important difference between the above and the code that you have now is that the above is not evaluated until you actually try to iterate through the returned collection. If you want to evaluate results immediately, you can add a call to .ToList(). This is equivalent to your original code:
public static IEnumerable<Http> enumerate()
{ return cache.Keys.SelectMany(key => (List<Http>)cache[key]).ToList(); }

Is it possible to write multiple iterators for a type in C#?

So for a type like:
CoolCollection<T>
you could have:
foreach (T item in coolCollection)
{
...
}
foreach (CoolNode node in coolCollection)
{
...
}
If this isn't possible, maybe like foreach2, or some other way to iterate. Often times, I would really like more than 1 way of iterating on a type.
EDIT: Sorry if it wasn't clear. Basically CoolNode is a node that makes CoolCollection. CoolNode has a property called value to return T, but I need another iterator to return only CoolNodes.
EDIT2: I can't do coolCollection.Something to iterate, because CoolNodes are connected via a property called Next, like a LinkedList. So I need to implement 2 iterators.
Just make CoolCollection<T> explicitly implement IEnumerable<CoolNode<T>> as well as IEnumerable<T>. (I'm guessing it's really CoolNode<T>, but if not, just take the extra <T> out everywhere.)
This will let you iterate in both manners, although you'll need a cast.
To do this, you'd need something like:
class CoolCollection<T> : ICollection<T>, IEnumerable<CoolNode<T>>
{
IEnumerator<CoolNode<T>> IEnumerable<CoolNode<T>>.GetEnumerator()
{
///...Do work here...
}
IEnumerator<T> GetEnumerator()
{
///...Do work here...
}
}
Using this would be like so:
foreach (T item in coolCollection)
{
...
}
foreach (CoolNode<T> node in (IEnumerable<CoolNode<T>>)coolCollection)
{
...
}
The other option would be to expose a property for the "nodes", so you could do:
foreach(var nodes in coolCollection.Nodes)
{ ... }
To implement this, you'd change things around a little bit. You'd need to make a private class that implemented the enumerator... something like:
class CoolCollection<T> : ICollection<T>
{
private List<CoolNode<T>> nodes;
IEnumerable<CoolNode<T>> Nodes
{
get
{
foreach(var node in this.nodes) { yield return node; }
}
}
}
If I understand the question correctly...
You could do it similar to the some of the other collection objects do it:
for example:
foreach (int key in IDictionary.Keys)
{
}
foreach (object value in IDictionary.Values)
{
}
But I don't think there is a way to do exactly the way you have it written...
No, you can't do that. You can not overload your default iterator.
Imagine if you could overload your default iterator.
What would this do? foreach (object o in foo) , there would be no logical way to choose the right iterator.
What you can do is have a second method named ForEach2 that iterates through your collection in a different way. Or you could explicitly implement an interface. Or you could use Linq composition for this kind of stuff.
From a class design perspective:
interface IBar {
IEnumerator<string> GetEnumerator();
}
class Foo : IBar, IEnumerable<int> {
// Very bad, risky code. Enumerator implementations, should
// line up in your class design.
public IEnumerator<int> GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
IEnumerator<string> IBar.GetEnumerator()
{
yield return "hello";
}
// must be IEnumerable if you want to support foreach
public IEnumerable<string> AnotherIterator
{
get {
yield return "hello2";
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
LINQ extensions for EachPair
struct Pair<T> {
public T First;
public T Second;
}
static class LinqExtension {
public static IEnumerable<Pair<T>> EachPair<T>(this IEnumerable<T> input) {
T first = default(T);
bool gotFirst = false;
foreach (var item in input)
{
if (!gotFirst)
{
first = item;
gotFirst = true;
}
else {
yield return new Pair<T>() { First = first, Second = item };
gotFirst = false;
}
}
}
}
Test code:
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foreach (int number in foo)
{
Console.WriteLine(number);
}
// LINQ composition - a good trick where you want
// another way to iterate through the same data
foreach (var pair in foo.EachPair())
{
Console.WriteLine("got pair {0} {1}", pair.First, pair.Second);
}
// This is a bad and dangerous practice.
// All default enumerators should be the same, otherwise
// people will get confused.
foreach (string str in (IBar)foo)
{
Console.WriteLine(str);
}
// Another possible way, which can be used to iterate through
// a portion of your collection eg. Dictionary.Keys
foreach (string str in foo.AnotherIterator)
{
Console.WriteLine(str);
}
}
If CoolCollection implements IEnumerable you can write:
foreach (var item in coolCollection)
{
...
}
or if T is CoolNode
foreach (CoolNode node in coolCollection)
{
...
}
If you need somehow transform each item to your type, you can use Linq Select operator:
foreach (CoolNode node in coolCollection.Select(item => ConvertToNode(item))
{
...
}
Take a look at the iterindex snippet. In your class, type iterindex and hit [TAB]. It will help you implement a "Named Iterator and Indexer" pattern.
The result can by used like this:
foreach (var e in myTree.DepthFirstView) // supports iteration
{
if (e == myTree.DepthFirstView[2]) // supports indexing
{
// ...
}
}
(I wrote this snippet, but I suspect it has never been put to good use. Ever.)

Categories

Resources