.NET或LINQ是否提供了重复应用函数的任何标准方法,直到结果满足终止条件并返回所有结果的IEnumerable
?
例如,假设您有一棵树并且想要找到从节点到根的路径:那么该函数是“获取节点n的父节点”,终止标准是“节点是根”。
这是一个带整数值的小例子,其中函数是“返回半值”,终止条件是“值为0”:
static void Main(string[] args)
{
int val = 4321;
List<int> pathToRoot = new List<int>{val};
for (;;)
{
val = GetParent(val);
if (val == 0)
{
break;
}
pathToRoot.Add(val);
}
// Prints: 4321,2160,1080,540,270,135,67,33,16,8,4,2,1
Console.WriteLine(string.Join(",", pathToRoot));
}
private static int GetParent(int child)
{
return child / 2;
}
我想用标准的.NET或LINQ方法替换for
循环。如果我必须自己编写该功能,它将如下所示:
public static class Generator
{
public static IEnumerable<T> ApplyRepeatedly<T>(T seed,
Func<T, T> func, Func<T, bool> predicate)
{
yield return seed;
for (;;)
{
seed = func(seed);
if (predicate(seed))
{
yield break;
}
yield return seed;
}
}
你会像这样使用它:
IEnumerable<int> pathToRoot = Generator.ApplyRepeatedly(
4321, GetParent, i => i == 0);
由于我不想重新发明轮子,我的问题是:.NET或LINQ是否已提供类似ApplyRepeatedly<T>()
的内容?
答案 0 :(得分:0)
System.Linq中没有任何内容,但F#有seq.unfold
所以你可以使用它:
var uf = FSharpFunc<int, FSharpOption<Tuple<int, int>>>.FromConverter(i =>
{
if (i == 0) return FSharpOption<Tuple<int, int>>.None;
else return FSharpOption<Tuple<int, int>>.Some(Tuple.Create(i, i / 2));
});
IEnumerable<int> pathToRoot = SeqModule.Unfold(uf, 4321);