C#でdelegateとtempleteを使ってMap-Reduceを作ってみた。

public class CollectionUtilities
{
	public delegate T MapFunction(T aElement);
	public static void Map(IList aList, MapFunction aFunction)
	{
		for (int i = 0; i < aList.Count; i++)
		{
			aList[i] = aFunction(aList[i]);
		}
	}

	public delegate S ReduceFunction(S aSummary, E aElement);
	public static S Reduce(IEnumerable aEnumerable, S aInitialValue, ReduceFunction aFunction)
	{
		S tSummary = aInitialValue;
		foreach (E tElement in aEnumerable)
		{
			tSummary = aFunction(tSummary, tElement);
		}
		return tSummary;
	}
}

Mapは全ての要素に対して何か処理を行いたいときに使えます。
例えば、全ての要素を+1したい場合

int[] aData = new int[] { 1, 2, 3 };

// 足してみる
CollectionUtilities.Map(aData, delegate(int aElement)
{
	return aElement + 1;
});

// 表示はこんな感じで
CollectionUtilities.Map(aData, delegate(int aElement)
{
	System.Console.WriteLine(aElement); return aElement;
});

結果

2
3
4

Reduceは全ての要素を処理して、一値の結果を作りたいときに使えます。
例えば、全ての要素を足したい場合

System.Console.WriteLine(CollectionUtilities.Reduce(new int[] { 1, 2, 3 }, 0, delegate(int aSummary, int aElement)
{
	return aSummary + aElement;
}));

結果

6

結果の型は入力要素の型と異なっていてもかまいません。
例えば、全ての要素を文字列連結したい場合

System.Console.WriteLine(CollectionUtilities.Reduce(new int[] { 1, 2, 3 }, "@", delegate(string aSummary, int aElement)
{
	return aSummary + aElement;
}));

結果

@123

組み合わせて使うと、なんか嬉しいらしい。MapReduce

2009/06/15 結果の型は入力要素の型と異なる場合を追記

カテゴリー: 技術情報

2件のコメント

koreyasu · 2007-08-14 20:32

名前自体は始めて知ったけれども、別にどうって事ない考えと言うか、
あのプロジェクトがまさにこれなわけで(笑
SQLで言えばSELECT/GROUPになるのかな。

とりあえず、これ自体よりもMapTaskとReduceTaskを気軽に作って、組み込めて、組み合わせれる環境の方が興味そそるね。

squld · 2007-08-16 11:42

そうやねぇ。OSレベルでサポートして、パイプみたいに使えるようになってるのが綺麗だね。

現在コメントは受け付けていません。