假设我想要一个包含10个数字的序列,并且我有一个按需生成数字的函数:
var s = new List<int>();
for (var i=0; i<10; i++) {
s.Add(Magically_generate_a_very_special_number());
}
通常是实现这一目标的方法。但是,假设我想使用LINQ。我已经可以做了(让我们忽略类型之间的区别):
var s = Enumerable.Range(0, 10).Select(i => MathNet.Numerics.Statistics.DescriptiveStatistics())
这对我来说几乎已经足够了。然而,令我困扰的是我需要首先指定一系列整数 - 这是一个多余的步骤,因为我无论如何都要丢弃这个值。是否有可能做以下事情?
var s = Enumerable.ObjectMaker(Magically_generate_a_very_special_number).Take(10);
似乎Enumerable.Repeat
几乎做了我想要的,但是它接受我给它的函数的结果,然后重复它,而不是重复评估函数。
顺便提一下,这个问题的灵感来自于Math.Net IContinuousDistribution.Samples
方法。它的身体如下:
while (true)
{
yield return Generate_a_random_number();
}
这样您就可以使用myDistribution.Samples.Take
从分布中获取一系列样本。原则上,我可以用同样的方式编写自己的方法来生成迭代器,但我想知道是否有一个已经存在的迭代器。
答案 0 :(得分:2)
您可以尝试使用foreach方法:
Enumerable.Take(10).ToList().Foreach(Magically_generate_a_very_special_number);
Downnside imho是你必须在两者之间做一个ToList。
编辑误读问题,所以nvmd:)
答案 1 :(得分:1)
您可以创建一个引用您的Magically_generate_a_very_special_number
方法的10个方法委托的序列,然后连续调用它们。
var s = Enumerable.Repeat<Func<int>>(generate, 10).Select(f => f());
答案 2 :(得分:1)
我认为你的Enumerable.ObjectMaker
之类的东西不是LINQ的一个方便部分,但是你可以使它完全像它一样。
public static IEnumerable<T> ObjectMaker<T>(Func<T> generator) {
while (true)
yield return generator();
}
var s = ObjectMaker(MagicallyGenerateVerySpecialNumber).Take(10);
答案 3 :(得分:0)
我同意丹麦语:我认为尝试在基础linq中进行操作比在for循环中执行它更难以阅读。似乎打败了linq的目的。
那就是说,也许你可以做一个扩展方法。只要你的Magically_generate_a_very_special_number
函数不需要参数,像这样的东西应该做你想要的:
public static void Fill<T>(this IList<T> list, int repeat, Func<T> fn) {
for (int i = 0; i < repeat; i++) list.Add(fn());
}
然后像这样使用:
s.Fill(10, Magically_generate_a_very_special_number);
答案 4 :(得分:0)
我们可以创建一个新方法来生成N个对象,方法是调用生成函数N次,遵循LINQ方法的一般模式,这样就可以满足您的确切需求:
public static IEnumerable<T> Generate<T>(Func<T> generator, int count)
{
for (int i = 0; i < count; i++)
yield return generator();
}
现在你可以写:
var numbers = Generate(Magically_generate_a_very_special_number, 10);