• 10个让朋友对你刮目相看的CoffeeScript单行代码绝技
    时间:2012-07-27   作者:artdialog   出处:artdialog.iteye.com

    或许你已经看过了Marcus Kazmierczak的这篇在HN上颇受欢迎的“10个让朋友对你刮目相看的Scala单行代码绝技”了, 尽管我对Scala并不了解(Java也是),但是这看起来还真不错,于是我也有点手痒, 想让我的朋友们也对我刮目相看一小下——不过不是从Java到Scala,我是从Javascript到CoffeeScript, 下面的例子都是基于node.js环境的。

    1. 列表中的每项乘2

    Marcus的第一个例子演示了map函数,我们可以使用range语法以及一个匿名函数来完成同样的事情:

    [1..10].map (i) -> i*2  

    我们还有下面这个更易读的版本:

    i * 2 for i in [1..10]  

    2. 数列求和

    Javascript(以及CoffeeScript扩展)同样有原生的map以及reduce函数:

    [1..1000].reduce (t, s) -> t + s  

    (reduce == reduceLeft, 还有reduceRight)  

    3. 检查字符串是否包含某个单词

    这实在是再简单不过了,因为我们有some方法,只要数组中的任何元素满足条件它就会返回true:

    wordList = ["coffeescript", "eko", "play framework", "and stuff", "falsy"]  

    tweet = "This is an example tweet talking about javascript and stuff."  

    wordList.some (word) -> ~tweet.indexOf word  

    下面的语句会返回匹配到的单词:

    wordList.filter (word) -> ~tweet.indexOf word  

    ~在CoffeeScript中并不是什么特别的操作符,这里我们使用了一个小技巧,它实际上就是按位取反操作符, 会对数值按位进行取反操作,在上面的例子里它相当于-x-1,这里我们用它来检查数组的下标是否大于-1, 因为-(-1)-1 == 0,会返回false。

    4. 读取文件

    使用客户端Javascript框架的用户会对下面的代码感到很亲切:

    fs.readFile 'data.txt', (err, data) -> fileText = data  

    你还可以使用同步版本:

    fileText = fs.readFileSync('data.txt').toString()  

    不过在node.js中,你只有在程序启动时才可以使用同步版本,其它时间你都应该使用异步版本。

    5. 生日快乐

    首先,先来一个Scala版本的映射版,不过我对字符串做了一点篡改:

    [1..4].map (i) -> console.log "Happy Birthday " + (if i is 3 then "dear Robert" else "to You")  

    下面再来一个优化版,这个读起来更像伪代码了:

    console.log "Happy Birthday #{if i is 3 then "dear Robert" else "to You"}" for i in [1..4]  

    6. 过滤数列

    将一个数字序列过滤为两种类型,这已经很接近了:

    passed = []  

    failed = []  

    (if score > 60 then passed else failed).push score for score in [49, 58, 76, 82, 88, 90]  

    (也可以使用filter,但是那样就不是一行了。。。)

    7. 读取并解析一个XML Web service

    XML是个神马东东?从没听过,让我们把它换成json,你可以使用request库:

    request.get { uri:'path/to/api.json', json: true }, (err, r, body) -> results = body  

    8. 找到一个数列的最小(最大)值

    我们有非常棒的apply函数,它可以让你通过一个数组来调用拥有可变参数的函数:Math.max以及Math.min, 这两个函数都接受可变长度参数,比如Math.max 30, 10, 20返回30,让我们试试下面的代码:

    Math.max.apply @, [14, 35, -7, 46, 98] # 98  

    Math.min.apply @, [14, 35, -7, 46, 98] # -7  

    9. 并行处理

    这个还不行,你可以创建子进程并自己和它们进行通讯, 或者使用WebWorkers API实现,让我们跳过这个。

    10. 埃拉托斯特尼筛法

    (译者注:埃拉托斯特尼筛法是古希腊数学家埃拉托斯特尼所提出的一种简单的判定素数的算法,详细介绍请参见维基百科)

    一行可以搞定?

    sieve = (num) ->  

        numbers = [2..num]  

        while ((pos = numbers[0]) * pos) <= num  

            delete numbers[i] for n, i in numbers by pos  

            numbers.shift()  

        numbers.indexOf(num) > -1  

    更新 (06/05): @dionyziz 发给了我这个更简洁的版本:

    primes = []  

    primes.push i for i in [2..100] when not (j for j in primes when i % j == 0).length  

    现在我们可以像原始版一样用一行来完成判定了:

    (n) -> (p.push i for i in [2..n] when not (j for j in (p or p=[]) when i%j == 0)[0]) and n in p  

    或者是下面这样:

    (n) -> (p.push i for i in [2..n] when !(p or p=[]).some((j) -> i%j is 0)) and n in p  

    11. 奖励

    最后,再奖励你们一个你肯定没见过的最易读的fizzbuzz(数3,数5游戏)版本:

    "#{if i%3 is 0 then 'fizz' else ''}#{if i%5 is 0 then 'buzz' else ''}" or i for i in [1..100]  

    更新:基于satyr的提示,这里是一个更简单,也更取巧的版本:

    ['fizz' unless i%3] + ['buzz' unless i%5] or i for i in [1..100]  

    如果你对数组使用+操作符,它会变成一个字符串,当数组中包含undefined或是null时,[].toString()和[].join(',')是一个效果,这在Javascript中也同样有效([undefined] + "b" === "b")

    结论

    我很吃惊这些例子中的一些语法居然和Scala如此接近,而我原以为它应该是属于另外一个星球的编程语言。

    网友留言/评论

    我要留言/评论

    相关文章

    程序员学英语:老实说,我对于英语的认识,从没有把它的重要性放到一个足够的高度上来,从去年下半年开始,接触到越来越多的英文材料,也随着视野的开阔,逐渐发现英文能力,是程序员个人发展的必备技能。在很多情况下,它的重要性可以用“致命”来形容。以前有同事说,程序员职业生涯的发展,起到决定作用的,绝大多数时候都不是技术和业务,而是其他被人忽视的“软实力”,譬如沟通、性格、英文等等。兴许我现在正在渐渐参悟这句话的含义。
    程序员看法上的几个典型错误:今天我不谈抱负理想,也不谈具体的技术,我来谈几个看法上的典型错误。下面的这些问题都是我曾经遇到,或者是我的朋友们遇到过的问题,这些都是我个人的理解,希望对大家有帮助。
    读《神一样的产品经理》:随着iPhone的风靡全球,乔帮主也把产品经理推到了极致,在看了《神一样的产品经理》后,借着ITeye的活动,发一点牢骚。
    技术文化建设实践:众所周知,良好的技术文化不仅有助于人才成长和提升团队内聚力,更是吸引和留住优秀人才的一大法宝。然而,该如何营造良好的技术文化呢?且听本期三位嘉宾的经验分享。本文是专题《怎样营造良好的技术文化》中的第三篇。第一篇是张克军带来的《悉心营造良好的技术文化》,第二篇是许晓斌分享的《分享促进技术文化建设》。
    有关创业公司融资最常被问的问题集锦:很多的创业公司都是沿着一个老套路:一个创业者,一个理想,一个计划就开始自己的创业。往往一提到创业人们就是人潮涌动,而单独一人上路的比有自己的雇员的创业者更加数不胜数。但是谈到成功,许多创业公司必要更深度的一整套的技能和经验。相信创业者们融资时面对投资商所提的这些问题可以引起一些反思。
    移动app设计的那些创新点:移动互联网发展得热火朝天,各种app层出不穷,我们看到了很多创新精巧的小应用,但是也有越来越多的应用同质化严重,与同类产品差异化较小。其实很多让人感觉很有新意的应用,只是找到了一个很小很别致的切入点。或者是抓住了用户的某一种心里,或者是在界面布局上大胆突破,或者是做了很少有人关注到的细分领域,或者是让人产生了真实生活中的亲切感。下面就来聊聊这些新颖别致的创新点。
    如何做一个优秀的领导者:TeamLeader是比较尴尬的角色,是从技术往管理的一个尝试性的阶段,这个阶段是比较辛苦的。
    效果图进阶展现,给效果图赋予思想和生命:设计师所做的每个作品都像是自己的孩子一样,在孕育的过程中思考了很多,但这些思考的过程、思考的方法并不是单单一张效果图就能够展现的;设计师有很多专业层面的认知,效果图上并不能展现,加上设计本来就是相对感性的,所以很多时候分歧就这样产生了。
    产品经理(尤其是创业的)需要懂技术吗?懂到什么程度?:最近七年,我都在做互联网产品,其中前五年分别在创业公司和上市公司里,做别人的产品;近两年在创业,做自己的产品。
    5大诀窍助你打造更加简洁的用户界面:本文作者Jake Rocheleau,社交媒体爱好者兼互联网企业家。他在文中根据自己的个人经验,向我们阐述了一些关于如何设计极简主义的网站界面的诀窍。这里提到的极简主义设计,就是剔除所有多余的元素,将设计保留在最基本的状态下,说来简单,实际上在当今习惯于绚丽与渐变的网站界面设计中,使用极简并非想象中这么容易。