早上看园友的一篇文章《lambda与闭包》,忽然间想起了以前刚学Python,刚接触FP时的高兴劲。对FP的no-side-effect的向往,对Declaration式编程的喜爱,让我对于编程,对于另一种程序设计的思想有了种转变。
还记得那时,看到Python中的built-in函数Filter,Map,Reduce,心想为什么.NET的BCL中怎么就没有呢。C#3.0出来以后,基本上已经可以DIY一个山寨版的Filter,Map,Reduce了,看代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FuncPro
{
class Program
{
static T[] Filter<T>(Func<T, bool> func, IEnumerable<T> iSource)
{
List<T> iResult = new List<T>();
foreach (var item in iSource)
{
if (func(item))
iResult.Add(item);
}
return iResult.ToArray();
}
static T[] Map<T>(Func<T, T> func, IEnumerable<T> iSource)
{
List<T> iResult = new List<T>();
foreach (var item in iSource)
{
iResult.Add(func(item));
}
return iResult.ToArray();
}
static T Reduce<T>(Func<T, T, T> func, IEnumerable<T> iSource)
{
T sum = default(T);
foreach (var item in iSource)
{
sum = func(sum, item);
}
return sum;
}
static void PrintArray(int[] iSource)
{
Console.Write("\t");
iSource.ToList().ForEach(x => Console.Write("{0} ", x));
Console.WriteLine();
}
static void Indent(string msg)
{
Console.WriteLine("{0}:", msg);
}
static void Main(string[] args)
{
int[] iSource = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Indent("Source");
PrintArray(iSource);
int[] iFilterResult = Filter(x => x > 5, iSource);
Indent("Filter, item more than 5");
PrintArray(iFilterResult);
int[] iMapResult = Map(x => x * 2, iSource);
Indent("Map, multiple with 2");
PrintArray(iMapResult);
int iReduceResult = Reduce((x, y) => x + y, iSource);
Indent("Reduce");
Console.Write("\t{0}\n ", iReduceResult);
Console.ReadKey();
}
}
}
前些日子和一个朋友闲聊到.NET加入了很多函数式编程的元素,应该可以写出函数式编程风格的代码来,也应该算是支持函数式编程的语言了,今天随手写了代码感觉确实是这样了。
PS.
今天看《CLR via C# 3e》时看到Jefferey利用扩展方法(Extension Method)来提高代码可读性的例子,我将上面的代码重构了一下,以提高可读性:
static class ExtendMethod
{
public static void ShowItems<T>(this IEnumerable<T> collection)
{
Console.Write("\t");
collection.ToList().ForEach((x) => Console.Write("{0} ", x));
Console.WriteLine();
}
}
class Program
{
static T[] Filter<T>(Func<T, bool> func, IEnumerable<T> iSource)
{
List<T> iResult = new List<T>();
foreach (var item in iSource)
{
if (func(item))
iResult.Add(item);
}
return iResult.ToArray();
}
static T[] Map<T>(Func<T, T> func, IEnumerable<T> iSource)
{
List<T> iResult = new List<T>();
foreach (var item in iSource)
{
iResult.Add(func(item));
}
return iResult.ToArray();
}
static T Reduce<T>(Func<T, T, T> func, IEnumerable<T> iSource)
{
T sum = default(T);
foreach (var item in iSource)
{
sum = func(sum, item);
}
return sum;
}
static void PrintArray(int[] iSource)
{
Console.Write("\t");
iSource.ToList().ForEach(x => Console.Write("{0} ", x));
Console.WriteLine();
}
static void Indent(string msg)
{
Console.WriteLine("{0}:", msg);
}
static void Main(string[] args)
{
int[] source = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Indent("Source");
source.ShowItems();
int[] filterResult = Filter(x => x > 5, source);
Indent("Filter, item more than 5");
filterResult.ShowItems();
int[] mapResult = Map(x => x * 2, source);
Indent("Map, multiple with 2");
mapResult.ShowItems();
int reduceResult = Reduce((x, y) => x + y, source);
Indent("Reduce");
new[] { reduceResult }.ShowItems();
Console.ReadKey();
}
}
Comments: