Pythonのmap, zip, enumerate, rangeをLinqで

以下のコード例では、以下stub内のコードのみを示す。また、Zip以外はC# 3.0を使用する。

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

class Test
{
    static void Main(string[] args)
    {
        // stub
    }
}

map

Selectを使う。

int[] nums = {1, 2, 3, 4, 5};
var q = nums.Select((n) => n * 2);
foreach (var e in q) {
    Console.Write(e + " ");
}
// 実行結果
// 2 4 6 8 10

ちなみに、foreachを使用しないで書くには以下のようにする。

int[] nums = {1, 2, 3, 4, 5};
nums.Select((n) => n * 2).ToList().ForEach((x) => {
    Console.Write(x + " ");
});
// 実行結果
// 2 4 6 8 10 

zip

C# 4.0から導入されるZipを使用する。プロトタイプは以下。

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
    this IEnumerable<TFirst> first,
    IEnumerable<TSecond> second,
    Func<TFirst, TSecond, TResult> func);
string[] s1 = new string[] {"a", "b", "c"};
int[] s2 = new int[] {1, 2, 3};
var q = s1.Zip(s2, (a, b) => a + b);
foreach (var e in q) {
    Console.Write(e + " ");
}
// 実行結果
// a1 b2 c3 

enumerate

Selectを使う。

string[] s = {"a", "b", "c"};
var q = s.Select((x,i) => new {Value=x, Index=i});
foreach (var e in q) {
    Console.WriteLine("{0}: {1}", e.Index, e.Value);
}
// 実行結果
// 0: a
// 1: b
// 2: c

拡張メソッドを使って自分で実装する方法。差分でなく全コードを示す。

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

static class Foo
{
    public static void Enumerate<T>(this IEnumerable<T> ie, Action<int, T> action) {
        var i = 0;
        foreach (var e in ie) action(i++, e);
    }
}

class Test {
    static void Main(string[] args)
    {
        string[] s = {"a", "b", "c"};
        s.Enumerate((i,x) => {
            Console.WriteLine(i + ": " + x);
        });
        // 実行結果
        // 0: a
        // 1: b
        // 2: c
    }
}

range

Enumerable.Rangeを使用する。注意点としては、Range(a, b)は、aで始まるb個の整数を表す。

var L = Enumerable.Range(0, 10);
foreach (var x in L) {
    Console.Write(x + " ");
}
// 実行結果
// 0 1 2 3 4 5 6 7 8 9