天天看點

10個驚豔的 CoffeeScript 單行代碼10個驚豔的 CoffeeScript 單行代碼

【譯者注】:譯者對coffeescript不太了解,隻是覺得這種單行代碼還挺有藝術感的,于是粗糙地翻譯出來分享給大家,有不對的地方還請指出來: )

10個驚豔的 CoffeeScript 單行代碼10個驚豔的 CoffeeScript 單行代碼

<a></a>

marcus從炫耀 <code>map</code> 函數開始。我們可以使用字面範圍和匿名函數做到完全相同的事情:

<code>[1..10].map (i) -&gt; i*2</code>

更多表現形式

<code>i * 2 for i in [1..10]</code>

javascript(以及coffeescript的擴充),也有本地map和reduce函數:

<code>[1..1000].reduce (t, s) -&gt; 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) -&gt; ~tweet.indexof word</code>

傳回比對的word:

<code>wordlist.filter (word) -&gt; ~tweet.indexof word</code>

~ 在coffeescript中不是一個特殊的運算符,隻是一個鬼把戲而已。它是一個按位取非運算符,即反轉操作數的二進制數字。在實踐中它相當于-x-1。這裡它的工作原理是檢查索引是否大于-1,并且 – ( – 1)-1 == 0計算為false。

javascript架構的用戶端使用者熟悉這個一種思路:

<code>fs.readfile 'data.txt', (err, data) -&gt; filetext = data</code>

你也可以使用同步版本:

<code>filetext = fs.readfilesync('data.txt').tostring()</code>

在node.js中,這僅接受應用程式的啟動程式。你應該在你的代碼中使用異步版本。

首先,輸出一個1對1的映射集合,并在中間混合插入一小段字元串:

<code>[1..4].map (i) -&gt; 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 &gt; 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) -&gt; p[+(c &lt; 60)].push c; p), [[],[]]</code>

xml是什麼?不曾聽說過。那麼不妨使用requst庫擷取json:

<code>request.get { uri:'path/to/api.json', json: true }, (err, r, body) -&gt; 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) -&gt;</code>

<code>numbers = [2..num]</code>

<code>while ((pos = numbers[0]) * pos) &lt;= num</code>

<code>delete numbers[i] for n, i in numbers by pos</code>

<code>numbers.shift()</code>

<code>numbers.indexof(num) &gt; -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) -&gt; (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) -&gt; (p.push i for i in [2..n] when !(p or p=[]).some((j) -&gt; 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.