日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Functional ProgrammingLazy Code:被我忘记的迭代器

發布時間:2023/11/29 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Functional ProgrammingLazy Code:被我忘记的迭代器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文給出一個Functional Programming和Lazy Code的一個例子。跟著思路走,關鍵的地方會有相應的說明。

我們想實現一個判斷"素數"的小程序,如下:

using System;namespace FunctionalProgramming {class Program{static void Main(string[] args){var number = int.Parse(Console.ReadLine());var result = true;for(long i=2;i<number;i++){if(number%i==0){result = false;break;}}Console.WriteLine(result);}} }

上面的代碼雖能完成功能,但不夠整潔。不是我們想要的代碼。
我們提取其中的方法,重新實現如下:

using System;namespace RefactorExample {class Program{static void Main(string[] args){var number = int.Parse(Console.ReadLine());var result = IsPrime(number);;Console.WriteLine(result);}//Refactorprivate static bool IsPrime(int number){var result=true;for (long i = 2; i < number; i++){if (number%i == 0){result = false;break;}}return result;}} }

以此為基礎,借助擴展方法,針對一個數組,我們可以方便的改寫上面的代碼如下:

using System; using System.Collections.Generic; using System.Linq;namespace AHigherCalling {static class Program{static void Main(string[] args){var number = new [] {3,5,7,9,11,13};foreach (var prime in number.Find(IsPrime).Take(2)){Console.WriteLine(prime);}Console.ReadKey();}private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){var result = new List<int>();foreach (var value in values){if (test(value))result.Add(value);}return result;}private static bool IsPrime(int value){var result = true;for (long i = 2; i < value; i++){if (value % i == 0){result = false;break;}}return result;}//一些其他的類似IsPrime的方法private static bool IsEven(int value){return value%2 == 0;}private static bool IsOdd(int value){return value%2 != 0;}} }

這樣做的目的是提供更清潔的語法,并提高程序應對變化的能力。例如,我們實現的兩個類似IsPrime方法。

單看Find方法。貌似沒有什么問題,當然我們可以用ReShaper生成LINQ語句,替換掉那個for循環。

View Code using System; using System.Collections.Generic; using System.Linq;namespace AHigherCalling {static class Program{static void Main(string[] args){var number = new [] {3,5,7,9,11,13};foreach (var prime in number.Find(IsPrime).Take(2)){Console.WriteLine(prime);}Console.ReadKey();}private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){//LINQ替換掉了for循環return values.Where(value => test(value)).ToList();}private static bool IsPrime(int value){var result = true;for (long i = 2; i < value; i++){if (value % i == 0){result = false;break;}}return result;}//一些其他的類似IsPrime的方法private static bool IsEven(int value){return value%2 == 0;}private static bool IsOdd(int value){return value%2 != 0;}} }

程序正常運行。
貌似我們的程序沒有什么問題了,那是因為我們這個數組不夠大!我們把numbers變的很大!如下:

using System; using System.Collections.Generic; using System.Linq;namespace AHigherCalling {static class Program{static void Main(string[] args){foreach (var prime in GetRandomNumbers().Find(IsPrime).Take(2)){Console.WriteLine(prime);}Console.ReadKey();}private static IEnumerable<int> GetRandomNumbers(){//yield return 3;//yield return 5;//yield return 7;//yield return 9;//yield return 11;//yield return 13;Random random = new Random();while (true){yield return random.Next(90000, 100000);}}private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){//LINQ替換掉了for循環return values.Where(value => test(value)).ToList();}private static bool IsPrime(int value){var result = true;for (long i = 2; i < value; i++){if (value % i == 0){result = false;break;}}return result;}//一些其他的類似IsPrime的方法private static bool IsEven(int value){return value%2 == 0;}private static bool IsOdd(int value){return value%2 != 0;}} }

程序就也陷入死循環了!而我這次想獲取的只是其前2個而已。
問題出在哪里?

不難發現,當然在Find這里!

還記得前面我實現的Find方法嗎?如下:

private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){var result = new List<int>();foreach (var value in values){if (test(value))result.Add(value);}return result;}

使用ReShaper重構過如下:

private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){//LINQ替換掉了for循環return values.Where(value => test(value)).ToList();}

簡單分析問題所在后,可以想到的解決方法,如下:

使用迭代器:

private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){foreach (var value in values){if (test(value))yield return value;}}

或是:

private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){return values.Where(value => test(value));}

這樣程序就按我既定的想法運行了。

從ReShaper生成的代碼來看,問題出在立即執行的ToList()那里!但畢竟ReShaper只是個工具,其翻譯的是我們的代碼,不推卸責任的說,問題出在我們,因為使用迭代器更正后,ReShaper不也生成了正確的代碼了么?

?

?

update:

from:?http://stackoverflow.com/questions/7062882/searching-a-tree-using-linq

總結

以上是生活随笔為你收集整理的Functional ProgrammingLazy Code:被我忘记的迭代器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。