是否有等效于以下的 LINQ?
static T Compose<T>(T source,
IEnumerable<Func<T, T>> funcs,
Func<T, bool> cond)
{
foreach (var func in funcs)
{
source = func(source);
if (cond(source)) break;
}
return source;
}
// This ends the composition as soon as a null is returned
var result = Compose(x, funcs, x => x == null);
Run Code Online (Sandbox Code Playgroud)
本质上,我希望将函数组合在一起,并在当前值匹配特定条件时中断。
result = f(g(h(x))) // if condition is met somewhere within this chain,
// it will immediately break and return
Run Code Online (Sandbox Code Playgroud)
编辑:我想到了一些类似的东西
funcs.Aggregate(seed, (x, f) => cond(x) ? x : f(x));
Run Code Online (Sandbox Code Playgroud)
但这看起来令人困惑,并且最终会枚举整个集合,而不是在满足条件时中断。
执行此操作的一种方法是Aggregate直到满足条件为止。因此,我定义了一个扩展方法:
public static TAccumulate AggregateUntil<TSource, TAccumulate>(
this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func,
Func<TAccumulate, bool> predicate)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (func == null)
throw new ArgumentNullException(nameof(func));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));
var accumulate = seed;
foreach (var item in source)
{
accumulate = func(accumulate, item);
if (predicate(accumulate)) break;
}
return accumulate;
}
Run Code Online (Sandbox Code Playgroud)
我们现在可以写成ComposeUntil:
public static T ComposeUntil<T>(
this IEnumerable<Func<T, T>> source,
T seed,
Func<T, bool> predicate)
{
return source.AggregateUntil(seed, (x, f) => f(x), predicate);
}
Run Code Online (Sandbox Code Playgroud)
并按以下方式使用它:
var funcs = new List<Func<int, int>>
{
x => x + 1,
x => x + 2,
x => x + 3,
x => x + 4
};
var result = funcs.ComposeUntil(0, x => x >= 6);
// result == 6
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1190 次 |
| 最近记录: |