[英]How to convert a for (not foreach) loop to Linq?
假設我想要一個由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
從分布中獲取樣本序列。 原則上,我可以編寫自己的方法以相同的方式生成迭代器,但是我想知道是否已經存在一個迭代器。
您可以嘗試使用foreach方法:
Enumerable.Take(10).ToList().Foreach(Magically_generate_a_very_special_number);
缺點恕我直言,您必須在兩者之間執行ToList。
編輯誤讀的問題,所以nvmd :)
您可以創建一個包含10個方法委托的序列,這些委托引用您的Magically_generate_a_very_special_number
方法,然后連續調用它們。
var s = Enumerable.Repeat<Func<int>>(generate, 10).Select(f => f());
我不認為像Enumerable.ObjectMaker
這樣的東西可以作為LINQ的便捷部分存在,但是您可以完全像它一樣制作一個。
public static IEnumerable<T> ObjectMaker<T>(Func<T> generator) {
while (true)
yield return generator();
}
var s = ObjectMaker(MagicallyGenerateVerySpecialNumber).Take(10);
我同意丹麥語:我認為嘗試在基本linq中進行操作比僅在for循環中進行操作更丑陋且更難以閱讀。 似乎打敗了linq的目的。
也就是說,也許您可以制作一個擴展方法。 只要您的Magically_generate_a_very_special_number
函數不需要參數,類似的事情就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);
我們可以通過按照LINQ方法的一般模式調用N次生成函數來創建一個新的方法來生成N個對象,這樣您就可以滿足您的確切需求:
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.