【譯者注】:譯者對coffeescript不太了解,隻是覺得這種單行代碼還挺有藝術感的,于是粗糙地翻譯出來分享給大家,有不對的地方還請指出來: )
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcukTa2NXN5QDN40GM2hDO58GN1AjMwEzLcRjMvwFNwYTMwIzLc1WdixWYvwFduVWboNWY0RXYvwVY0FGZvwVZt5CevJWcu42Y4VnbpxWLuR2Lc9CX6MHc0RHaiojIsJye.png)
<a></a>
marcus從炫耀 <code>map</code> 函數開始。我們可以使用字面範圍和匿名函數做到完全相同的事情:
<code>[1..10].map (i) -> i*2</code>
更多表現形式
<code>i * 2 for i in [1..10]</code>
javascript(以及coffeescript的擴充),也有本地map和reduce函數:
<code>[1..1000].reduce (t, s) -> t + s</code>
(<code>reduce</code> == <code>reduceleft</code>, <code>reduceright</code> 也可)
非常容易,因為方法不止一種。如果數組中的任何元素滿足函數的話就傳回true:
<code>wordlist = ["coffeescript", "eko", "play framework", "and stuff", "falsy"]</code>
<code>tweet = "this is an example tweet talking about javascript and stuff."</code>
<code></code>
<code>wordlist.some (word) -> ~tweet.indexof word</code>
傳回比對的word:
<code>wordlist.filter (word) -> ~tweet.indexof word</code>
~ 在coffeescript中不是一個特殊的運算符,隻是一個鬼把戲而已。它是一個按位取非運算符,即反轉操作數的二進制數字。在實踐中它相當于-x-1。這裡它的工作原理是檢查索引是否大于-1,并且 – ( – 1)-1 == 0計算為false。
javascript架構的用戶端使用者熟悉這個一種思路:
<code>fs.readfile 'data.txt', (err, data) -> filetext = data</code>
你也可以使用同步版本:
<code>filetext = fs.readfilesync('data.txt').tostring()</code>
在node.js中,這僅接受應用程式的啟動程式。你應該在你的代碼中使用異步版本。
首先,輸出一個1對1的映射集合,并在中間混合插入一小段字元串:
<code>[1..4].map (i) -> console.log "happy birthday " + (if i is 3 then "dear robert" else "to you")</code>
但這樣更好。讀起來像僞代碼:
<code>console.log "happy birthday #{if i is 3 then "dear robert" else "to you"}" for i in [1..4]</code>
過濾數組中的數字分為兩類。有文化的方式:
<code>(if score > 60 then (passed or passed = []) else (failed or failed = [])).push score for score in [49, 58, 76, 82, 88, 90]</code>
(感謝@giacecco幫助縮短了此處的代碼)
以及函數式方法:
<code>[passed, failed] = [49, 58, 76, 82, 88, 90].reduce ((p,c,i) -> p[+(c < 60)].push c; p), [[],[]]</code>
xml是什麼?不曾聽說過。那麼不妨使用requst庫擷取json:
<code>request.get { uri:'path/to/api.json', json: true }, (err, r, body) -> results = body</code>
<code>apply</code> 函數用在這裡非常友善。它允許你調用一個函數,傳遞數組作為參數清單:<code>math.max</code> 和<code>math.min</code> 都可以接收數量可變的參數,即<code>math.max 30, 10, 20</code> 傳回30。放到數組中:
<code>math.max.apply @, [14, 35, -7, 46, 98] # 98</code>
<code>math.min.apply @, [14, 35, -7, 46, 98] # -7</code>
我還沒有想到。你可以自己建立子程序,并與它們溝通,或者使用webworkers api實作。跳過。
無法把它減縮到一行代碼。思路是這樣的?
<code>sieve = (num) -></code>
<code>numbers = [2..num]</code>
<code>while ((pos = numbers[0]) * pos) <= num</code>
<code>delete numbers[i] for n, i in numbers by pos</code>
<code>numbers.shift()</code>
<code>numbers.indexof(num) > -1</code>
更新(6月/5日):@dionyziz發給我這個精簡版本:
<code>primes = []</code>
<code>primes.push i for i in [2..100] when not (j for j in primes when i % j == 0).length</code>
然後我們可以使用到真正的單行代碼,就像原來的那個一樣:
<code>(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</code>
或在某種程度上更高效
<code>(n) -> (p.push i for i in [2..n] when !(p or p=[]).some((j) -> i%j is 0)) and n in p</code>
大多數可讀的fizzbuzz版本,你可以看到:
<code>"#{if i%3 is 0 then 'fizz' else ''}#{if i%5 is 0 then 'buzz' else ''}" or i for i in [1..100]</code>
編輯:通過一個小提示使之更簡單,但更有技巧:
<code>['fizz' unless i%3] + ['buzz' unless i%5] or i for i in [1..100]</code>
當你在數組中使用 <code>+</code> 運算符時,它會轉換為字元串。<code>[].tostring()</code>和<code>[].join(',')</code>相同,它在數組值<code>undefined</code>或<code>null</code>情況下,給出一個空的字元串。這也适用于javascript(<code>[undefined] + "b" === "b"</code>)。
現代程式設計語言的表達令人驚訝。同樣我令我驚訝的是,這些映射中的一些文法是如此相似于scala,但這兩種語言卻遠隔萬水千山。
本文來自雲栖社群合作夥伴“linux中國”
原文釋出時間為:2013-04-02.