I am writing a few extensions to mimic the map and reduce functions in Lisp.
我正在编写一些扩展来模仿地图并减少Lisp中的函数。
public delegate R ReduceFunction<T,R>(T t, R previous);
public delegate void TransformFunction<T>(T t, params object[] args);
public static R Reduce<T,R>(this List<T> list, ReduceFunction<T,R> r, R initial)
{
var aggregate = initial;
foreach(var t in list)
aggregate = r(t,aggregate);
return aggregate;
}
public static void Transform<T>(this List<T> list, TransformFunction<T> f, params object [] args)
{
foreach(var t in list)
f(t,args);
}
The transform function will cut down on cruft like:
转换功能将减少如下:
foreach(var t in list)
if(conditions && moreconditions)
//do work etc
Does this make sense? Could it be better?
这有意义吗?会更好吗?
4 个解决方案
#1
35
These look very similar to extensions in Linq already:
这些看起来非常类似于Linq中的扩展:
//takes a function that matches the Func<T,R> delegate
listInstance.Aggregate(
startingValue,
(x, y) => /* aggregate two subsequent values */ );
//takes a function that matches the Action<T> delegate
listInstance.ForEach(
x => /* do something with x */);
Why is the 2nd example called Transform? Do you intend to change the values in the list somehow? If that's the case you may be better off using ConvertAll<T>
or Select<T>
.
为什么第二个例子叫做Transform?你打算以某种方式更改列表中的值吗?如果是这种情况,您最好使用ConvertAll
#2
48
According to this link Functional Programming in C# 3.0: How Map/Reduce/Filter can Rock your World the following are the equivalent in C# under the System.Linq namespace:
根据这个链接C#3.0中的函数编程:Map / Reduce / Filter如何可以撼动您的世界,以下是System.Linq命名空间中C#的等价物:
- map --> Enumerable.Select
- reduce --> Enumerable.Aggregate
- filter --> Enumerable.Where
map - > Enumerable.Select
reduce - > Enumerable.Aggregate
过滤器 - > Enumerable.Where
#3
2
I would use the built in Func delegates instead. This same code would work on any IEnumerable. Your code would turn into:
我会使用内置的Func委托代替。这个相同的代码适用于任何IEnumerable。您的代码将变为:
public static R Reduce<T,R>(this IEnumerable<T> list, Func<T,R> r, R initial)
{
var aggregate = initial;
foreach(var t in list)
aggregate = r(t,aggregate);
return aggregate;
}
public static void Transform<T>(this IEnumerable<T> list, Func<T> f)
{
foreach(var t in list)
f(t);
}
#4
1
You might want to add a way to do a map but return a new list, instead of working on the list passed in (and returning the list can prove useful to chain other operations)... perhaps an overloaded version with a boolean that indicates if you want to return a new list or not, as such:
您可能希望添加一种方法来执行映射但返回一个新列表,而不是处理传入的列表(并返回列表可以证明链接其他操作很有用)...也许是一个带有布尔值的重载版本如果你想要返回一个新的列表,如下:
public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
params object [] args)
{
return Transform(list, f, false, args);
}
public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
bool create, params object [] args)
{
// Add code to create if create is true (sorry,
// too lazy to actually code this up)
foreach(var t in list)
f(t,args);
return list;
}
#1
35
These look very similar to extensions in Linq already:
这些看起来非常类似于Linq中的扩展:
//takes a function that matches the Func<T,R> delegate
listInstance.Aggregate(
startingValue,
(x, y) => /* aggregate two subsequent values */ );
//takes a function that matches the Action<T> delegate
listInstance.ForEach(
x => /* do something with x */);
Why is the 2nd example called Transform? Do you intend to change the values in the list somehow? If that's the case you may be better off using ConvertAll<T>
or Select<T>
.
为什么第二个例子叫做Transform?你打算以某种方式更改列表中的值吗?如果是这种情况,您最好使用ConvertAll
#2
48
According to this link Functional Programming in C# 3.0: How Map/Reduce/Filter can Rock your World the following are the equivalent in C# under the System.Linq namespace:
根据这个链接C#3.0中的函数编程:Map / Reduce / Filter如何可以撼动您的世界,以下是System.Linq命名空间中C#的等价物:
- map --> Enumerable.Select
- reduce --> Enumerable.Aggregate
- filter --> Enumerable.Where
map - > Enumerable.Select
reduce - > Enumerable.Aggregate
过滤器 - > Enumerable.Where
#3
2
I would use the built in Func delegates instead. This same code would work on any IEnumerable. Your code would turn into:
我会使用内置的Func委托代替。这个相同的代码适用于任何IEnumerable。您的代码将变为:
public static R Reduce<T,R>(this IEnumerable<T> list, Func<T,R> r, R initial)
{
var aggregate = initial;
foreach(var t in list)
aggregate = r(t,aggregate);
return aggregate;
}
public static void Transform<T>(this IEnumerable<T> list, Func<T> f)
{
foreach(var t in list)
f(t);
}
#4
1
You might want to add a way to do a map but return a new list, instead of working on the list passed in (and returning the list can prove useful to chain other operations)... perhaps an overloaded version with a boolean that indicates if you want to return a new list or not, as such:
您可能希望添加一种方法来执行映射但返回一个新列表,而不是处理传入的列表(并返回列表可以证明链接其他操作很有用)...也许是一个带有布尔值的重载版本如果你想要返回一个新的列表,如下:
public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
params object [] args)
{
return Transform(list, f, false, args);
}
public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
bool create, params object [] args)
{
// Add code to create if create is true (sorry,
// too lazy to actually code this up)
foreach(var t in list)
f(t,args);
return list;
}