可能已经读过Marcus Kazmierczak博客中的《 10 Scala One Liners to Impress Your Friends 》。虽然我不懂Scala(以及Java),但是它看上去真心不错,所以我决定也要惊艳我的朋友一番——人家从Java到Scala,我从Javascript到CoffeeScript。假设所有例子使用node.js作为环境。
【译者注】:译者对CoffeeScript不太了解,只是觉得这种单行代码还挺有艺术感的,于是粗糙地翻译出来分享给大家,有不对的地方还请指出来:)
1.数组中的每个元素乘以2
Marcus从炫耀 map
函数开始。我们可以使用字面范围和匿名函数做到完全相同的事情:
更多表现形式
2.数组中的元素求和
Javascript(以及CoffeeScript的扩展),也有本地map和reduce函数:
[1..1000].reduce (t, s) -> t + s
(reduce
== reduceLeft
, reduceRight
也可)
3.验证word在字符串中是否存在
非常容易,因为方法不止一种。如果数组中的任何元素满足函数的话就返回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
返回匹配的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.生日快乐
首先,输出一个1对1的映射集合,并在中间混合插入一小段字符串:
[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.过滤数组中的数字
过滤数组中的数字分为两类。有文化的方式:
(
if
score > 60
then
(passed or passed = [])
else
(failed or failed = [])).push score
for
score
in
[49, 58, 76, 82, 88, 90]
(感谢@giacecco帮助缩短了此处的代码)
以及函数式方法:
[passed, failed] = [49, 58, 76, 82, 88, 90].reduce ((p,c,i) -> p[+(c < 60)].push c; p), [[],[]]
7.获取并解析一个XML Web服务
XML是什么?不曾听说过。那么不妨使用requst库获取JSON:
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]
Math.min.apply @, [14, 35, -7, 46, 98]
9.并行处理
我还没有想到。你可以自己创建子进程,并与它们沟通,或者使用WebWorkers API实现。跳过。
10.埃拉托斯特尼筛法
无法把它减缩到一行代码。思路是这样的?
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
更新(6月/5日):@dionyziz发给我这个精简版本:
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版本,你可以看到:
"#{if i%3 is 0 then 'fizz' else ''}#{if i%5 is 0 then 'buzz' else ''}"
or i
for
i
in
[1..100]
编辑:通过一个小提示使之更简单,但更有技巧:
[
'fizz'
unless i%3] + [
'buzz'
unless i%5] or i
for
i
in
[1..100]
当你在数组中使用 +
运算符时,它会转换为字符串。[].toString()
和[].join(',')
相同,它在数组值undefined
或null
情况下,给出一个空的字符串。这也适用于Javascript([undefined] + "b" === "b"
)。
结论
现代编程语言的表达令人惊讶。同样我令我惊讶的是,这些映射中的一些语法是如此相似于Scala,但这两种语言却远隔万水千山。
出处: 码农网 原文:ricardo
时间: 2016-04-26 08:32
来源 :开源中国社区
作者 :码农网
原文链接