内容简介:昨天在看C#函数式编程这本书的时候,有一处让我干着急,需求是这样: 给多行文字加上数字列表项。针对这个需求你会如何快捷高效的给每个项目加上数字编号呢? 我看书中是这样实现的,如下代码
一:背景
昨天在看C#函数式编程这本书的时候,有一处让我干着急,需求是这样: 给多行文字加上数字列表项。
针对这个需求你会如何快捷高效的给每个项目加上数字编号呢? 我看书中是这样实现的,如下代码
public class Program { public static void Main(string[] args) { var list = new List<string>() { "cnblogs","csdn","zhihu","oschina" }; var items = list.Zip(Enumerable.Range(1, list.Count + 1), (item, i) => $"{i}. {item}").ToList(); items.ForEach(Console.WriteLine); } } ------------------- output ------------------- 1. cnblogs 2. csdn 3. zhihu 4. oschina Press any key to continue . . .
怎么说呢,需求能实现没有问题,但这里还是累赘了,因使用到了拉链函数Zip 和生成范围的Range,全纠缠到一块,有没有更简单粗暴的方式呢? 其实你只用Select的一个带迭代变量的重载方法就可以搞定,但现实中还是有很多的 程序员 不会使用或者说不知道,所以优化后的代码如下。
var items = list.Select((item, i) => $"{i + 1}. {item}").ToList(); ------------------- output ------------------- 1. cnblogs 2. csdn 3. zhihu 4. oschina Press any key to continue . . .
二:源码探究
相信编码多年的我们无数次的在憎恨foreach没有带上索引,这么普罗大众的需求尽然都没有实现,而 python 这样的语言早就给实现了,为了解决这个不足,我还得需要单独定义一个变量在迭代时即时记录,烦不胜烦,就像下面这样。
var index = 0; foreach (var item in list) { index++; Console.WriteLine(item); }
可能FCL类库程序员也深有体会,所以加了一个可以在迭代中获取当前index的绝妙方法,这么:cow::nose:造福人类的方法却发现身边知道的人少之又少,小遗憾哈。
1. ILSpy查看源码
从下面代码的 SelectIterator 枚举类可以看到,其实在底层也是单独给你定义了一个index,然后逐一回调给你的回调函数,这种封装很有必要,不过全是高阶函数,功底很深哈!
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) { if (source == null) { throw Error.ArgumentNull("source"); } if (selector == null) { throw Error.ArgumentNull("selector"); } return SelectIterator(source, selector); } private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) { int index = -1; foreach (TSource item in source) { index = checked(index + 1); yield return selector(item, index); } }
三:其他案例
其实有太多例子需要使用迭代器中的index值了,比如最近业务中要计算各个月份的环比率,用今天讲到的这个方法就可以非常完美的解决,简化后的代码如下。
public static void Main(string[] args) { var list = new List<int>() { 10, 20, 30,40,50, 60,70,80,90,100,110,120, }; var rateList = list.Select((item, index) => { return index == 0 ? 0 : Math.Round(((decimal)list[index] - list[index - 1]) / list[index - 1], 2); }).ToList(); rateList.ForEach(Console.WriteLine); } ------------------- output ------------------- 0 1 0.5 0.33 0.25 0.2 0.17 0.14 0.12 0.11 0.1 0.09 Press any key to continue . . .
好了,本篇来自于触景生情,希望您编码有帮助。
如您有更多问题与我互动,扫描下方进来吧~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 迭代器萃取与反向迭代器
- 浅谈python可迭代对象,迭代器
- 可迭代对象,迭代器(对象),生成器(对象)
- 终于把动态规划与策略迭代、值迭代讲清楚了
- 终于把动态规划与策略迭代、值迭代讲清楚了
- 搞清楚 Python 的迭代器、可迭代对象、生成器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beautiful Code
Greg Wilson、Andy Oram / O'Reilly Media / 2007-7-6 / GBP 35.99
In this unique work, leading computer scientists discuss how they found unusual, carefully designed solutions to difficult problems. This book lets the reader look over the shoulder of major coding an......一起来看看 《Beautiful Code》 这本书的介绍吧!