CoffeeScriptを知らない友人にCoffeeScriptを紹介する10のワンライナーテクニック
って、日本のギークならそういうんだろうなー
みなさんCoffeeScript使ってますか?ちょっとjsわかる人ならすぐ覚えられて、文法が平易で、かつRubyやPythonぽく拡張されてるので非常にストレスが少ないです
しかも、元のJSの特性をほとんど妨げないようになってるので、jsでできてcoffeeでできないことはほとんどない。(まったくない、かはちゃんと確かめてませんが… ないと思います)
雰囲気、インデントブロックのRuby記法のような印象。
というわけで元ネタは 10 CoffeeScript One Liners to Impress Your Friends | ricardo.cc です
CoffeeScriptインストール済なら、$ coffee -i、もしくは $ coffee で対話インタプリタ起動します
1. リストに含まれるアイテムを2倍に
coffeescriptはレンジのリテラルと無名関数を使って配列操作ができます
[1..10].map (i) -> i*2
あるいはこのように書くことも。
i * 2 for i in [1..10]
前者はRubyっぽい。Pythonistaには後者かな。
2. リストの中身を足し合わせる
javascriptに元からある機能ですが、map、reduce的なことができます。
1でmap使ってますね
[1..1000].reduce (t, s) -> t + s
(reduce == reduceLeft, reduceRight is also available)
3. ある単語が文の中に存在するか確認する
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にだけ存在する汚いトリックじゃないです。 thx:@uasi
~ は CoffeeScript にだけ存在する演算子ではなく、ただの汚いトリックである、云々
It is the bitwise NOT operator, which inverts the bits of it's operand. In practice it equates to -x-1. Here it works on the basis that we want to check for an index greater than -1, and -(-1)-1 == 0 evaluates to false.
4. ファイルを読む
これはnode.js使ってる場合ですが…
ファイルを扱うfs関数をrquireして使います
非同期でやる
fs.readFile 'data.txt', (err, data) -> fileText = data
同期でやる
fileText = fs.readFileSync('data.txt').toString()
node.js使う限り非同期が推奨。だけどワンライナーなら同期のほうが便利かも。
coffeescriptの対話インタプリタは補完が効かないのでやりづらいですが…
5. Happy Birthday
3のときだけ Robert へ。
[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]
後置の for 便利。
6. 数を分類
リストに入ってる数を二つに分類します
passed = [] failed = [] (if score > 60 then passed else failed).push score for score in [49, 58, 76, 82, 88, 90]
(could also use filter but then it wouldn't be a one-liner...)
7. XMLをとってきてパースする
requestっていうライブラリを使ってJSONに置き換えちゃいます。
request.get { uri:'path/to/api.json', json: true }, (err, r, body) -> results = body
これはPythonのrequestsライブラリのインスパイアかなー
シンプルで覚えやすい仕様,パワフルなPythonのWebアクセスモジュール request | TRIVIAL TECHNOLOGIES on CLOUD
8. リストから最大もしくは最小の数を探す
Math.max.apply @, [14, 35, -7, 46, 98] # 98 Math.min.apply @, [14, 35, -7, 46, 98] # -7
CoffeeScriptでは @ はthisのことです
9. 並列処理
WebWorkersのAPI使って並列処理できます。できるっていってるだけでコードは例示されてないですね…。
そりゃWebWorker使えばできるでしょうけど。
Not there yet. You can create child processes on your own and communicate with them, or use the WebWorkers API implementation. Skipping over.
10. エラトステネスの篩
Couldn't get this down to one line. Ideas?
最初に書いた版
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
@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. おまけ
"#{if i%3 is 0 then 'fizz' else ''}#{if i%5 is 0 then 'buzz' else ''}" or i for i in [1..100]
5の応用ですね
シンプルだが、若干トリッキーなもの
['fizz' unless i%3] + ['buzz' unless i%5] or i for i in [1..100]
Arrayに+演算子を使うと、文字列に変換されます
.toString() は .join(',') と同じ。
これは Javascirptでも ([undefined] + "b" === "b") です
原文ここまで
12. jsf**k
っていうので思い出したんですが… id:voqnの人がjsで何やら楽しそうなことをやってまして
_=-~-~-~[];__=[][(![]+[])[_-_]+([][[]]+[])[_+_-_/_]+(![]+[])[_-_/_]+(!![]+[])[_-_]+(!![]+[])[_]+(!![]+[])[_/_]]+[];___=__[_]+__[_+_]+__[_-_/_]+(![]+[])[_]+(!![]+[])[_-_]+(!![]+[])[_/_]+(!![]+[])[_-_/_]+__[_]+(!![]+[])[_-_]+__[_+_]+(!![]+[])[_/_];___[___][___]((![]+[])[_/_]+(![]+[])[(_+_)/_]+(!![]+[])[_]+(!![]+[])[_/_]+(!![]+[])[_-_]+"(\""+'\\'+(([][[]]+[])[_-_])+(_)+(_-_)+(_+_/_)+(_+_)/_+"\");")();
これで、utf8の「あ」が返ってきます
coding as drawing: wtf!? JavaScript Empty Array Programming
いやーワンライナーって奥が深いですね(白目)