underscore中的集合操作

underscore.js中的集合操作 书接前文,我们在上一篇中将一个文本划分成了单词的数组,并统计了每个单词出现的频率。现在我们需要将排行前10的单词找出来。那么第一步就是将所有单词按照频率排序,然后将这个集合的前10个拿出来。 underscore.js为集合提供了丰富的API,这与函数式编程的鼻祖LISP语言有着直接的继承关系。LISP围绕着List提供了的众多函数。 排序 var contacts = [ { "name": "Juntao", "age": 29 }, { "name": "Abruzzi", "age": 30 }, { "name": "Sara", "age": 29 } ]; 比如想要将上面这个集合按照age排序,可以使用sortBy函数: var sorted = _(contacts).sortBy("age"); 默认的sortBy的返回值是按照升序排列的,不过JavaScript的数组原生就有reverse的API用以翻转数组,因此如果要得到降序的排列,只需要: var sorted = _(contacts).sortBy("age").reverse(); 抽取 有时候,我们需要从众多的信息中抽取自己关心的,比如上例中的contacts集合,我们在界面上仅仅需要name属性组成的集合,这时候可以通过pluck来完成抽取: var names = _.pluck(contacts, "name"); //["juntao", "abruzzi", "sara"] underscore.js默认的pluck只能抽取一层,如果遇到下面这种场景: var contacts = [ { "name": "Juntao", "age": 29, "address": { "street": "Dengling Rd" } }, { "name": "Sara", "age": 29, "address": { "street": "Zhangba 4th Rd" } } ] 想要抽取address....

February 21, 2015 3 min

略论函数式编程

JavaScript中的map/reduce 在过去的10年间,不论你是否对大数据有所涉足,你肯定听过map/reduce这个貌似很高大上的词。这个高大上的词事实上来自于函数式编程世界。map的意思是影射,即将一个集合中的内容,通过应用某种函数,形成另外一个集合。reduce表示求和,或者规约,即将一个集合以某种函数规约为一个值。 underscore.js是一个非常强大的JavaScript库,也是我的工具箱里的必备品。事实上在我自己的小项目中,我更倾向于使用jQuery+underscore.js来完成所有的功能,而不是使用诸如AngularJS之类的框架。 作为一个库,underscore.js提供了丰富的API来操作JavaScript中的集合,对象,函数等,可以节省程序员大量的时间,我们在这篇文章中来看看underscore.js中基本的函数式编程特性。 使用map消除for-loop 我们先来看一个小例子:我们要编写一个名为makeQuery的函数,它接受一个JavaScript对象和一个分隔符,然后将JavaScript对象展开,形成key=value[分隔符key=value]的形式。正如下面这个测试所反映的: it("make query from object", function() { var cookies = { "JSESSIONID": "6C729E682C05AA56017E3D1675CE8E5F", "_USER": "GEO-NASTAR" }; var expected = "JSESSIONID=6C729E682C05AA56017E3D1675CE8E5F;_USER=GEO-NASTAR"; expect(makeQuery(cookies, ";")).toEqual(expected); }); 一个直接的解决方案是: function makeQuery(obj, delimiter) { var strArray = []; for (var key in obj) { strArray.push(key + "=" + obj[key]); } return strArray.join(delimiter); } 我们再来看另外一个小例子:给定一个字符串(人名)数组,将数组中的所有人名都变成大写字母开头。正如下面这个测试所反映: it("capitalize", function() { var names = ["juanchen", "mingliang", "lu", "juntao"]; var expected = ["Juanchen", "Mingliang", "Lu", "Juntao"]; expect(capitalize(names))....

February 20, 2015 3 min

制作一个多彩的svn diff脚本

Code Review 在ThoughtWorks,我们几乎每天都会进行一个叫code review或者code diff的活动:每天下午5:00,团队成员围坐在一起,将今天的修改大概过一下,这样做的好处非常明显: 分享业务知识,了解彼此的工作 分享技术细节,比如有人使用了某种设计模式 帮助别人发现问题,比如逻辑错误等,群策群力 经过实践,code reivew可以快速发现问题,而且可以尽可能多的分享知识,是一种ThoughtWorker们喜闻乐见的学习/娱乐形式。 但是随着项目的不同,各个团队使用的版本管理工具都不一样。用惯了git的非常漂亮的diff子命令之后,svn的diff简直就是战五渣。没有高亮,没有进度条,就是黑底白字的一些文本,实在无法让人提起兴趣。 这篇文章分享一个简单的方法,可以让你很容易的把svn的diff打造成一个漂亮的工具: diff格式 Diff是一种通用的表示文本差异的格式,细节可以看我之前写过一篇关于diff和patch的文章。需要说明的是,它作为一种标准格式,很多编辑器都提供对这种格式的高亮显示,比如现在非常流行的Sublime Text编辑器: 默认的,svn的diff命令会生成这样朴素的输出: 命令行的diff高亮显示 在Mac下,可以通过brew来安装一个命令行工具,这个工具可以将Diff格式高亮显示: $ brew install colordiff 有了这个工具,就可以将svn生成的Diff格式高亮显示出来: $ svn diff | colordiff 但是你可能已经发现这些神奇的^M,这是Windows系统中的换行符在Unix类系统中的展示,我们需要将Diff先转换一次: $ svn diff | dos2unix | colordiff 如果你的系统中没有dos2unix,可以用brew来安装: $ brew install dos2unix unix2dos 分页器 *nix系统下有两种分页器:more和less,less比more的功能更丰富。less有很多的参数,我们这里选用了3个常见的: -s: 压缩连续的空白行为一行 -M: 给出更多的提示信息,包含行号,百分比等 +Gg: 先跳至要查看文件的末尾,再跳至文件开头,这样从less就可以得到整个流的长度,从而计算出正确的百分比。当然如果是单独文件时,less是明确知道文件长度的,但是如果是从流中重定向过来的文本,less无法在开始时就得知长度。 下面这条命令可以将当前目录下的所有html文件分屏显示,并且在每一屏的最后一行显示百分比等信息: $ cat *.html | less -s -M +Gg 放在一起 好了,我们将每个部分都已经讲解了一遍了,现在让我们将这些零件串起来,在svn的working copy中执行这条命令就可以得到非常漂亮的,分页显示的Diff: $ svn diff | dos2unix | colordiff | less -s -M +Gg 当然,还可以用一个alias(别名)来节省敲入的字符数:...

February 18, 2015 1 min