Functional ProgrammingLazy Code:被我忘记的迭代器
本文給出一個(gè)Functional Programming和Lazy Code的一個(gè)例子。跟著思路走,關(guān)鍵的地方會(huì)有相應(yīng)的說(shuō)明。
我們想實(shí)現(xiàn)一個(gè)判斷"素?cái)?shù)"的小程序,如下:
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);}} }上面的代碼雖能完成功能,但不夠整潔。不是我們想要的代碼。
我們提取其中的方法,重新實(shí)現(xiàn)如下:
以此為基礎(chǔ),借助擴(kuò)展方法,針對(duì)一個(gè)數(shù)組,我們可以方便的改寫(xiě)上面的代碼如下:
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;}//一些其他的類(lèi)似IsPrime的方法private static bool IsEven(int value){return value%2 == 0;}private static bool IsOdd(int value){return value%2 != 0;}} }這樣做的目的是提供更清潔的語(yǔ)法,并提高程序應(yīng)對(duì)變化的能力。例如,我們實(shí)現(xiàn)的兩個(gè)類(lèi)似IsPrime方法。
單看Find方法。貌似沒(méi)有什么問(wèn)題,當(dāng)然我們可以用ReShaper生成LINQ語(yǔ)句,替換掉那個(gè)for循環(huán)。
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循環(huán)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;}//一些其他的類(lèi)似IsPrime的方法private static bool IsEven(int value){return value%2 == 0;}private static bool IsOdd(int value){return value%2 != 0;}} }程序正常運(yùn)行。
貌似我們的程序沒(méi)有什么問(wèn)題了,那是因?yàn)槲覀冞@個(gè)數(shù)組不夠大!我們把numbers變的很大!如下:
程序就也陷入死循環(huán)了!而我這次想獲取的只是其前2個(gè)而已。
問(wèn)題出在哪里?
不難發(fā)現(xiàn),當(dāng)然在Find這里!
還記得前面我實(shí)現(xiàn)的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重構(gòu)過(guò)如下:
private static IEnumerable<int> Find(this IEnumerable<int> values,Func<int,bool> test ){//LINQ替換掉了for循環(huán)return values.Where(value => test(value)).ToList();}簡(jiǎn)單分析問(wèn)題所在后,可以想到的解決方法,如下:
使用迭代器:
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));}這樣程序就按我既定的想法運(yùn)行了。
從ReShaper生成的代碼來(lái)看,問(wèn)題出在立即執(zhí)行的ToList()那里!但畢竟ReShaper只是個(gè)工具,其翻譯的是我們的代碼,不推卸責(zé)任的說(shuō),問(wèn)題出在我們,因?yàn)槭褂玫鞲?#xff0c;ReShaper不也生成了正確的代碼了么?
?
?
update:
from:?http://stackoverflow.com/questions/7062882/searching-a-tree-using-linq
總結(jié)
以上是生活随笔為你收集整理的Functional ProgrammingLazy Code:被我忘记的迭代器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 做梦梦到老太太死了好吗
- 下一篇: 梦到棺材和猪是什么意思