C#でRubyっぽく

いったい何番煎じなのか.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnumTest
{
  static class EnumUtil
  {
    public static IEnumerable<TRet> Zip<T1, T2, TRet> ( 
        this IEnumerable<T1> src1, IEnumerable<T2> src2, Func<T1, T2, TRet> selector
    )
    {
      IEnumerator<T1> e1 = src1.GetEnumerator();
      IEnumerator<T2> e2 = src2.GetEnumerator();

      while (e1.MoveNext() && e2.MoveNext())
        yield return selector( e1.Current, e2.Current);
    }

    public static void Zip<T1, T2> ( 
        this IEnumerable<T1> src1, IEnumerable<T2> src2, Action<T1, T2> selector
    )
    {
      IEnumerator<T1> e1 = src1.GetEnumerator();
      IEnumerator<T2> e2 = src2.GetEnumerator();

      while (e1.MoveNext() && e2.MoveNext())
        selector( e1.Current, e2.Current);
    }

    public static IEnumerable<TRet> MapWithIndex<T1, TRet> ( 
        this IEnumerable<T1> src1, Func<T1, int, TRet> selector
    )
    {
      IEnumerator<T1> e1 = src1.GetEnumerator();
      int i=0;
      while (e1.MoveNext())
        yield return selector( e1.Current, i++);
    }

    public static void EachWithIndex<T1> ( 
        this IEnumerable<T1> src1, Action<T1, int> selector
    )
    {
      IEnumerator<T1> e1 = src1.GetEnumerator();
      int i=0;
      while (e1.MoveNext())
        selector( e1.Current, i++);
    }

    public static IEnumerable<int> Integers(int i=0)
    {
      while(true) yield return i++;
    }

    public static void Times(this int n, Action<int> proc)
    {
      for (var i = 0; i < n; i++)
        proc(i);
    }

    public static void UpTo(this int b, int e, Action<int> proc)
    {
      for (var i = b; i <= e; i++)
        proc(i);
    }

    public static void DownTo(this int b, int e, Action<int> proc)
    {
      for (var i = b; i >= e; i--)
        proc(i);
    }

    public static void Step(this int b, int e, int s, Action<int> proc)
    {
      if (s>0)
      {
        for (var i = b; i <= e; i+=s)
          proc(i);
      } else if (s<0)
      {
        for (var i = b; i >= e; i+=s)
          proc(i);
      } else
      {
        ;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var list1 = new int[]{1,2,3,4,5,6};
      var list2 = new string[]{"a","b","c","d","e","f","g"};

      list1.EachWithIndex( (x,i) => {
        Console.WriteLine( string.Format("WeI: {0}/{1}", x, i ));
      });

      list1.Zip( list2, (x,y) => {
        Console.WriteLine( string.Format("Zip: {0}/{1}", x, y ));
      });

      foreach( var o in list1.Zip( list2, (x,y) => new {x,y}))
      {
        Console.WriteLine( string.Format("Zip2: {0}/{1}", o.x, o.y ));
      }

      list1.Zip( EnumUtil.Integers(), (x,y) => {
        Console.WriteLine( string.Format("Zip3: {0}/{1}", x, y ));
      });

      1.UpTo(5, i => Console.WriteLine( i.ToString()));
    }
  }
}