Friday, May 6, 2011

Question on modifying this custom iterator

I have the below code, which iterates over a list based on a custom algorithm:

        public static IEnumerable<TItem>
MakeCustomIterator<TCollection, TCursor, TItem>(
this TCollection collection, // Extension method of the collection used (eg List<T>)
TCursor cursor, // An array of ints which holds our progress
Func<TCollection, TCursor, TItem> getCurrent,
Func<TCursor, bool> isFinished,
Func<TCursor, TCursor> advanceCursor)
        {
            while (!isFinished(cursor)) // While we haven't reached the end of the iteration......
            {
                yield return getCurrent(collection, cursor);
                cursor = advanceCursor(cursor);

            }

        }


     var matrix = new List<List<double>> {
     new List<double> { 1.0, 1.1, 1.2 },
      new List<double> { 2.0, 2.1, 2.2 },
      new List<double> { 3.0, 3.1, 3.2 }
      };

     var iter = matrix.MakeCustomIterator(
     new int[] { 0, 0 },
     (coll, cur) => coll[cur[0]][cur[1]],
     (cur) => cur[0] > 2 || cur[1] > 2,
     (cur) => new int[] { cur[0] + 1,
       cur[1] + 1 });



            foreach (var item in iter)
            {

            }

When I use this code, it will get 1.0 and then 2.1 (diagonally below, in the next list). Is it possible to go from 1.0 to 1.1 in the first link? Or possible to go vertically down from 1.0 to 2.0?

Note: This code snippet is from Accelerated C# 2008.

Thanks

From stackoverflow
  • You just need to change the idea of what "advancing" means (potentially along with what "finished" means). For example, to just go "down" you'd use:

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2 || cur[1] > 2,
         // Increase the row, but stay on the same column
         (cur) => new int[] { cur[0] + 1, cur[1] });
    

    To go "along":

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2 || cur[1] > 2,
         // Stay on the same row, but increase the column
         (cur) => new int[] { cur[0], cur[1] + 1 });
    

    It would be trickier to go "along then down" but feasible:

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2,
         // Stay on the same row if we can, otherwise move to next row
         (cur) => cur[1] == 2 ? new int[] { cur[0] + 1, 0 }
                              : new int[] { cur[0], cur[1] + 1});
    
    dotnetdev : Thanks for that!

0 comments:

Post a Comment