tags:

views:

509

answers:

11

Can somebody provide a real life example regarding use of iterators. I tried searching google but was not satisfied with the answers.

+3  A: 

Iterate through the students in a class

The Iterator design pattern provides us with a common method of enumerating a list of items or array, while hiding the details of the list's implementation. This provides a cleaner use of the array object and hides unneccessary information from the client, ultimately leading to better code-reuse, enhanced maintainability, and fewer bugs. The iterator pattern can enumerate the list of items regardless of their actual storage type.

rahul
why not create an array of students and use index.
Rohit
why not create as many students as you need, each their own variable
Bryan Denny
Why even have Students, what's wrong with Object? ;-)
Winston Smith
why not make them global variables too, so they're easier to reference anywhere in your program?
Kyle Gagnet
@Bryan: My college had over 20,000 students. If you feel like making that many variables, go right ahead.@Rohit: What if it's not students but files on a filesystem arranged in a tree pattern? The tree may be stored in an array, but you'd have to do a lot of indexing tricks to get it right.
OwenP
@OwenP /sarcasm :)
Bryan Denny
@OwenP: Hopefully not all of them in one class :)
Halvard
+3  A: 

Iterate through a set of homework questions.

But seriously, Iterators can provide a unified way to traverse the items in a collection regardless of the underlying data structure.

Read the first two paragraphs here for a little more info.

Donut
+2  A: 

A couple of things they're great for:
a) For 'perceived performance' while maintaining code tidiness - the iteration of something separated from other processing logic.
b) When the number of items you're going to iterate through is not known.

Although both can be done through other means, with iterators the code can be made nicer and tidier as someone calling the iterator don't need to worry about how it finds the stuff to iterate through...

Real life example: enumerating directories and files, and finding the first [n] that fulfill some criteria, e.g. a file containing a certain string or sequence etc...

KristoferA - Huagati.com
A: 

An iterator is an easy way of implementing the IEnumerator interface. Instead of making a class that has the methods and properties required for the interface, you just make a method that returns the values one by one and the compiler creates a class with the methods and properties needed to implement the interface.

If you for example have a large list of numbers, and you want to return a collection where each number is multiplied by two, you can make an iterator that returns the numbers instead of creating a copy of the list in memory:

public IEnumerable<int> GetDouble() {
   foreach (int n in originalList) yield return n * 2;
}

In C# 3 you can do something quite similar using extension methods and lambda expressions:

originalList.Select(n => n * 2)

Or using LINQ:

from n in originalList select n * 2
Guffa
+7  A: 

Iterators are an abstraction that decouples the concept of position in a collection from the collection itself. The iterator is a separate object storing the necessary state to locate an item in the collection and move to the next item in the collection. I have seen collections that kept that state inside the collection (i.e. a current position), but it is often better to move that state to an external object. Among other thing it enables you to have multiple iterators iterating the same collection.

Martin Liversage
A: 

didn't you find this?

ArsenMkrt
+4  A: 

Simple example : a function that generates a sequence of integers :

public IEnumerable<int> GetSequence(int fromValue, int toValue)
{
    int direction = Math.Sign(toValue - FromValue);
    for (int i = fromValue; i <= toValue; i += direction)
    {
        yield return i;
    }
}

To do it without an iterator, you would need to create an array then enumerate it...

Thomas Levesque
Without an iterator, how would you enumerate it? :p
Svish
@Svish : with an *Enumerator*, not an iterator ;)
Thomas Levesque
ah :p
Svish
+1  A: 
IEnumerator<Question> myIterator = listOfStackOverFlowQuestions.GetEnumerator();
while (myIterator.MoveNext())
{
  Question q;
  q = myIterator.Current;
  if (q.Pertinent == true)
     PublishQuestion(q);
  else
     SendMessage(q.Author.EmailAddress, "Your question has been rejected");
}


foreach (Question q in listOfStackOverFlowQuestions)
{
    if (q.Pertinent == true)
        PublishQuestion(q);
    else    
        SendMessage(q.Author.EmailAddress, "Your question has been rejected");
}
Max
Not an iterator. :)
KristoferA - Huagati.com
I second that, but will remove my downvote if you rewrite this as an iterator.
John Saunders
Not exactly true. An implicit iterator is created. See http://en.wikipedia.org/wiki/Iterator#Implicit_iterators
pjp
This is not an iterator!
jpbochi
Still not an iterator. I suggest you try that link I posted for Rohit in the comments to the question.
John Saunders
Max - some languages call this an iterator. Specifically the question is referring to "iterator blocks" which are generally known a generators. in f# they are called "sequence expressions". The iterator in java maps pretty much exactly to the .net IEnumerable. Most c# developers would take "iterators" to mean iterator blocks with yield return (see my example) rateghr than simple enumerator instances.
ShuggyCoUk
+2  A: 

Beside everything else, to iterate through lazy-type sequences - IEnumerators. Each next element of such sequence may be evaluated/initialized upon iteration step which makes it possible to iterate through infinite sequences using finite amount of resources...

Ray
+2  A: 

The canonical and simplest example is that it makes infinite sequences possible without the complexity of having to write the class to do that yourself:

// generate every prime number
public IEnumerator<int> GetPrimeEnumerator()
{
    yield return 2;
    var primes = new List<int>();
    primesSoFar.Add(2);
    Func<int, bool> IsPrime = n => primes.TakeWhile(
        p => p <= (int)Math.Sqrt(n)).FirstOrDefault(p => n % p == 0) == 0;

    for (int i = 3; true; i += 2)
    {
        if (IsPrime(i))
        {
            yield return i;
            primes.Add(i);
        }
    }
}

Obviously this would not be truly infinite unless you used a BigInt instead of int but it gives you the idea. Writing this code (or similar) for each generated sequence would be tedious and error prone. the iterators do that for you. If the above example seems too complex for you consider:

// generate every power of a number from start^0 to start^n
public IEnumerator<int> GetPowersEnumerator(int start)
{   
    yield 1; // anything ^0 is 1
    var x = start;
    while(true)
    {
        yield x;
        x *= start;
    }      
}

They come at a cost though. Their lazy behaviour means you cannot spot common errors (null parameters and the like) until the generator is first consumed rather than created without writing wrapping functions to check first. The current implementation is also incredibly bad(1) if used recursively.

Wiriting enumerations over complex structures like trees and object graphs is much easier to write as the state maintenance is largely done for you, you must simply write code to visit each item and not worry about getting back to it.


  1. I don't use this word lightly - a O(n) iteration can become O(N^2)
ShuggyCoUk
+4  A: 

You've probably heard of arrays and containers - objects that store a list of other objects.

But in order for an object to represent a list, it doesn't actually have to "store" the list. All it has to do is provide you with methods or properties that allow you to obtain the items of the list.

In the .NET framework, the interface IEnumerable is all an object has to support to be considered a "list" in that sense.

To simplify it a little (leaving out some historical baggage):

public interface IEnumerable<T>
{
    IEnumerator<T> GetEnumerator();
}

So you can get an enumerator from it. That interface (again, simplifying slightly to remove distracting noise):

public interface IEnumerator<T>
{
    bool MoveNext();
    T Current { get; }
}

So to loop through a list, you'd do this:

var e = list.GetEnumerator();
while (e.MoveNext())
{
    var item = e.Current;

    // blah
}

This pattern is captured neatly by the foreach keyword:

foreach (var item in list)
    // blah

But what about creating a new kind of list? Yes, we can just use List<T> and fill it up with items. But what if we want to discover the items "on the fly" as they are requested? There is an advantage to this, which is that the client can abandon the iteration after the first three items, and they don't have to "pay the cost" of generating the whole list.

To implement this kind of lazy list by hand would be troublesome. We would have to write two classes, one to represent the list by implementing IEnumerable<T>, and the other to represent an active enumeration operation by implementing IEnumerator<T>.

Iterator methods do all the hard work for us. We just write:

IEnumerable<int> GetNumbers(int stop)
{
    for (int n = 0; n < stop; n++)
        yield return n;
}

And the compiler converts this into two classes for us. Calling the method is equivalent to constructing an object of the class that represents the list.

Daniel Earwicker
lovely answer !
Preets