views:

81

answers:

4

Iterating though an array isn’t a problem but what if I only wanted to incremented only when the method is called?

Im not even sure if this would work but is there an easier way of doing this

    int counter;
    string[] myArray = {"foo", "bar", "something", "else", "here"};

    private string GetNext()
    {
        string myValue = string.Empty;

        if (counter < myArray.Length) {
            myValue = myArray [counter];
        } else {
            counter = 0;
        }

        counter++;

        return myValue;
    }
+1  A: 

If I understand what you are wanting to do, I believe all you need to do is call the GetEnumerator() method on the array. The Enumerator object has a MoveNext() method that moves to the next item in the list, and returns true if it worked, and false if it didn't. You read the value of the enumerator with the Current property, and you can reset the counter to 0 with Reset

ckramer
+4  A: 

What you want is an iterator

private IEnumerable<String> myEnumarable()
{
    foreach(string i in myArray)
    {
       yield return i;
    }
}

However just calling myArray.GetEnumerator(); has the same effect.

You use it by

string[] myArray = { "foo", "bar", "something", "else", "here" };
IEnumerator<String> myEnum;

private string GetNext() //Assumes there will be allways at least 1 element in myArray.
{
    if(myEnum == null)
       myEnum = myArray.GetEnnumerator();
    if(!myEnum.MoveNext())
    {
       myEnum.Reset();
       myEnum.MoveNext();
    }
    return myEnum.Current;
}
Scott Chamberlain
+2  A: 

You could try this instead:

private string GetNext()
{
    string result = myArray[counter];
    counter = (counter + 1) % myArray.Length;
    return result;
}

Your code has a bug where "foo" is only returned the first time.

foo
bar
something
else
here
                <-- oops!
bar
something
else
here
Mark Byers
+1  A: 

The example you posted is basically an implementation of an enumerator, so yes it would work.

string[] _array = {"foo", "bar", "something", "else", "here"};

IEnumerable<String> GetEnumarable()
{
    foreach(string i in _array)
       yield return i;
}

If you want to do this with a custom data structure or want to put more logic when moving to the next element (i.e. lazy loading, streaming data) you can implement the IEnumerator interface yourself.

Example

public class EnumeratorExample : IEnumerator
{
    string[] _array;

    // enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;

    public EnumeratorExample(string[] array)
    {
        _array = list;
    }

    public bool MoveNext()
    {
        ++position;
        return (position < _array.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get { return Current; }
    }

    public string Current
    {
        get
        {
            try
            {
                return _array[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException("Enumerator index was out of range. Position: " + position + " is greater than " + _array.Length);
            }
        }
    }
}

References
- IEnumerable Interface

Dennis Roche