或許你已經看過了Marcus Kazmierczak的這篇在HN上頗受歡迎的「10個讓朋友對你另眼相看的Scala單行代碼絕技」了, 儘管我對Scala並不瞭解(Java也是),可是這看起來還真不錯,因而我也有點手癢, 想讓個人朋友們也對我另眼相看一小下——不過不是從Java到Scala,我是從Javascript到CoffeeScript, 下面的例子都是基於node.js環境的。javascript
Marcus的第一個例子演示了map函數,咱們可使用range語法以及一個匿名函數來完成一樣的事情:html
[1..10].map (i) -> i*2
咱們還有下面這個更易讀的版本:java
i * 2 for i in [1..10]
Javascript(以及CoffeeScript擴展)一樣有原生的map以及reduce函數:node
[1..1000].reduce (t, s) -> t + s (reduce == reduceLeft, 還有reduceRight)
這實在是再簡單不過了,由於咱們有some方法,只要數組中的任何元素知足條件它就會返回true:git
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
下面的語句會返回匹配到的單詞:github
wordList.filter (word) -> ~tweet.indexOf word
~在CoffeeScript中並非什麼特別的操做符,這裏咱們使用了一個小技巧,它實際上就是按位取反操做符, 會對數值按位進行取反操做,在上面的例子裏它至關於-x-1,這裏咱們用它來檢查數組的下標是否大於-1, 由於-(-1)-1 == 0,會返回false。web
使用客戶端Javascript框架的用戶會對下面的代碼感到很親切:算法
fs.readFile 'data.txt', (err, data) -> fileText = data
你還可使用同步版本:編程
fileText = fs.readFileSync('data.txt').toString()
不過在node.js中,你只有在程序啓動時纔可使用同步版本,其它時間你都應該使用異步版本。json
首先,先來一個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]
將一個數字序列過濾爲兩種類型,這已經很接近了:
passed = [] failed = [] (if score > 60 then passed else failed).push score for score in [49, 58, 76, 82, 88, 90]
(也可使用filter,可是那樣就不是一行了。。。)
XML是個神馬東東?從沒聽過,讓咱們把它換成json,你可使用request庫:
request.get { uri:'path/to/api.json', json: true }, (err, r, body) -> results = body
咱們有很是棒的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
這個還不行,你能夠建立子進程並本身和它們進行通信, 或者使用WebWorkers API實現,讓咱們跳過這個。
(譯者注:埃拉託斯特尼篩法是古希臘數學家埃拉託斯特尼所提出的一種簡單的斷定素數的算法,詳細介紹請參見維基百科)
一行能夠搞定?
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
最後,再獎勵大家一個你確定沒見過的最易讀的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如此接近,而我原覺得它應該是屬於另一個星球的編程語言。
你能夠在這裏瞭解更多關於CoffeeScript的知識, 以及代碼片斷, 也歡迎在Twitter上Follow @ricardobeat.