The LiveScript Book

 
 

The LiveScript Book

Generators and Yield

你可以在你的 LiveScript 代码中使用 Ecmascript 2015 中的的generatorsyield了!

1.function* f
2. yield \foo
3.
4.g = ->*
5. yield from f!
6. yield \bar
7.
8.h = g!
9.
10.h.next!.value + h.next!.value # => "foobar"

1.var g, h;
2.function* f(){
3. return (yield 'foo');
4.}
5.
6.g = function*(){
7. (yield* f());
8. return (yield 'bar');
9.};
10.h = g();
11.h.next().value + h.next().value;

你可以同过在function关键字后加*或者在箭头后加*来创建generators,对我们已经有的各种箭头,依然可以正常工作。

yieldjavascript 中的yield一样的,yield from等价于 JavaScript 中的yield*

If and Unless

有几种格式来使用if语句(if语句实际上是一个表达式,你可以按照表达式的方式去使用)。

1.if 2 + 2 == 4
2. 'something'
3.else
4. 'something else'
5.
6.if 2 + 2 == 4 then 'something' else 'something else'
7.
8.if 2 + 2 == 4
9.then 'something'
10.else 'something else'

1.if (2 + 2 === 4) {
2. 'something';
3.} else {
4. 'something else';
5.}
6.if (2 + 2 === 4) {
7. 'something';
8.} else {
9. 'something else';
10.}
11.if (2 + 2 === 4) {
12. 'something';
13.} else {
14. 'something else';
15.}

else是可选的,else if也是可以被允许的。

1.if 2 + 2 == 4
2. 'something'
3.
4.if 2 + 2 == 6
5. 'something'
6.else if 2 + 2 == 5
7. 'something else'
8.else
9. 'the default'

1.if (2 + 2 === 4) {
2. 'something';
3.}
4.if (2 + 2 === 6) {
5. 'something';
6.} else if (2 + 2 === 5) {
7. 'something else';
8.} else {
9. 'the default';
10.}

if语句可以被用作表达式:

1.result = if 2 / 2 is 0
2. then 'something'
3. else 'something else'

1.var result;
2.result = 2 / 2 === 0 ? 'something' : 'something else';

你也可以后置使用if,它比赋值运算的优先级低,使得如下可行:

1.x = 10
2.x = 3 if 2 + 2 == 4
3.x # => 3

1.var x;
2.x = 10;
3.if (2 + 2 === 4) {
4. x = 3;
5.}
6.x;

unless等价于if not

1.unless 2 + 2 == 5
2. 'something'
3.
4.x = 10
5.x = 3 unless 2 + 2 == 5

1.var x;
2.if (2 + 2 !== 5) {
3. 'something';
4.}
5.x = 10;
6.if (2 + 2 !== 5) {
7. x = 3;
8.}

that指向语义中的值,并且会进行存在检查。

1.time = days: 365
2.
3.half-year = that / 2 if time.days
4.# => 182.5
5.
6.if /^e(.*)/ == \enter
7. that.1 # => 'nter'
8.
9.if half-year?
10. that * 2
11.# => 365

1.var time, that, halfYear;
2.time = {
3. days: 365
4.};
5.if (that = time.days) {
6. halfYear = that / 2;
7.}
8.if (that = /^e(.*)/.exec('enter')) {
9. that[1];
10.}
11.if ((that = halfYear) != null) {
12. that * 2;
13.}

循环和推导式

for循环有三种基本形式。一个是在范围内迭代,一个是在列表内迭代,最后一个是通过键值对对对象进行迭代。

我们先来看看for基于范围的迭代,它的基本形式是这样的:
for (let) (VAR) (from NUM) (to|til NUM) (by NUM) (when COND)(几乎都是可选的)。

let会把循环体包进一个函数体内,然后会在循环时自动调用此函数。这个使得函数闭包非常方便。同时也可以使得你循环体中的变量不会暴露到循环外面!

from后接一个数字表示计数器从此数开始计数,省略from,默认是0

to或者til后接循环计数器的终止边界值。to表示少于等于,til表示严格少于。

by是步长,默认是1

whencase,|的语法糖)是一个可选的循环守护。

如果把for用作一个表达式,那么将返回一个list

1.ret = for i from 1 to 10 by 3
2. i
3.ret # => [1, 4, 7, 10]

1.var ret, res$, i$, i;
2.res$ = [];
3.for (i$ = 1; i$ <= 10; i$ += 3) {
4. i = i$;
5. res$.push(i);
6.}
7.ret = res$;
8.ret;

for...in对一个列表进行迭代。其结构是这样的:
for (let) (VAL-VAR) (, INDEX-VAR) in EXP (by NUM) (when COND)
再一次几乎所有的都是可选的。letbywhen跟前面讲的还是一样的。

VAL-VAR是当前列表项的值,INDEX-VARVAL-VAR所对应的下标索引值,任何一个都是可选的。

EXP得是一个数组。

1.for x in [1 2 3]
2. x
3.
4.xs = for let x, i in [1 to 10] by 2 when x %3 is 0
5. -> i + x
6.
7.xs[0] # => 5
8.xs[1] # => 17

1.var i$, ref$, len$, x, xs, res$;
2.for (i$ = 0, len$ = (ref$ = [1, 2, 3]).length; i$ < len$; ++i$) {
3. x = ref$[i$];
4. x;
5.}
6.res$ = [];
7.for (i$ = 0, len$ = (ref$ = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).length; i$ < len$; i$ += 2) {
8. if (ref$[i$] % 3 === 0) {
9. res$.push((fn$.call(this, i$, ref$[i$])));
10. }
11.}
12.xs = res$;
13.xs[0];
14.xs[1];
15.
16.function fn$(i, x) {
17. return function() {
18. return i + x;
19. };
20.}

for...of用来对一个对象进行迭代。结构是这样的:
for (own) (let) (KEY-VAR) (, VAL-VAR) of EXP (when COND)

又一次机会都是可选的,letwhen跟前面的一样。

own使用hasOwnProperty来检查属性,阻止对原型链上的属性进行迭代。

KEY-VAR是属性名,VAL-VAR是属性值,二者也都是可选的。

EXP得是一个对象。

1.for k, v of {a: 1, b: 2}
2. "#k#v"
3.
4.xs = for own let key, value of {a: 1, b: 2, c: 3, d: 4}
5. when value % 2 is 0
6. -> key + value
7.
8.xs[0]! # => 'b2'
9.xs[1]! # => 'd4'

1.var k, ref$, v, xs, res$, i$, own$ = {}.hasOwnProperty;
2.for (k in ref$ = {
3. a: 1,
4. b: 2
5. }) {
6. v = ref$[k];
7. k + "" + v;
8.}
9.res$ = [];
10.for (i$ in ref$ = {
11. a: 1,
12. b: 2,
13. c: 3,
14. d: 4
15. })
16. if (own$.call(ref$, i$)) {
17. if (ref$[i$] % 2 === 0) {
18. res$.push((fn$.call(this, i$, ref$[i$])));
19. }
20. }
21.xs = res$;
22.xs[0]();
23.xs[1]();
24.
25.function fn$(key, value) {
26. return function() {
27. return key + value;
28. };
29.}

循环嵌套的返回值也是相同结构的列表嵌套。

1.result = for x to 3
2. for y to 2
3. x + y
4.result
5.# => [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5]]

1.var result, res$, i$, x, lresult$, j$, y;
2.res$ = [];
3.for (i$ = 0; i$ <= 3; ++i$) {
4. x = i$;
5. lresult$ = [];
6. for (j$ = 0; j$ <= 2; ++j$) {
7. y = j$;
8. lresult$.push(x + y);
9. }
10. res$.push(lresult$);
11.}
12.result = res$;
13.result;

你可以在在in/of循环中省略一个或两个变量:

1.res = for , i in [1 2 3]
2. i
3.res # => [0, 1, 2]
4.
5.for til 3 then func!
6.
7.# calls func three times
8.
9.[6 for til 3] # => [6, 6, 6]

1.var res, res$, i$, len$, i;
2.res$ = [];
3.for (i$ = 0, len$ = [1, 2, 3].length; i$ < len$; ++i$) {
4. i = i$;
5. res$.push(i);
6.}
7.res = res$;
8.res;
9.for (i$ = 0; i$ < 3; ++i$) {
10. func();
11.}
12.for (i$ = 0; i$ < 3; ++i$) {
13. 6;
14.}

列表推导式总是生成一个列表。列表中的循环嵌套生成的列表还是一维的。

1.[x + 1 for x to 10 by 2 when x isnt 4]
2.# => [1, 3, 7, 9, 11]
3.
4.
5.["#{x}#{y}" for x in [\a \b] for y in [1 2]]
6.
7.# => ['a1', 'a2', 'b1', 'b2']

1.var i$, x, ref$, len$, j$, ref1$, len1$, y;
2.for (i$ = 0; i$ <= 10; i$ += 2) {
3. x = i$;
4. if (x !== 4) {
5. x + 1;
6. }
7.}
8.for (i$ = 0, len$ = (ref$ = ['a', 'b']).length; i$ < len$; ++i$) {
9. x = ref$[i$];
10. for (j$ = 0, len1$ = (ref1$ = [1, 2]).length; j$ < len1$; ++j$) {
11. y = ref1$[j$];
12. x + "" + y;
13. }
14.}

你可以使用空白格来使得列表推到式更优美。

1.[{id: id1, name, age} for {id: id1, name} in table1
2. for {id: id2, age} in table2
3. when id1 is id2]

1.var i$, ref$, len$, ref1$, id1, name, j$, len1$, ref2$, id2, age;
2.for (i$ = 0, len$ = (ref$ = table1).length; i$ < len$; ++i$) {
3. ref1$ = ref$[i$], id1 = ref1$.id, name = ref1$.name;
4. for (j$ = 0, len1$ = (ref1$ = table2).length; j$ < len1$; ++j$) {
5. ref2$ = ref1$[j$], id2 = ref2$.id, age = ref2$.age;
6. if (id1 === id2) {
7. ({
8. id: id1,
9. name: name,
10. age: age
11. });
12. }
13. }
14.}

你可以使用层叠来暗指所映射的那个值。

1.[.. + 1 for [1 2 3]] # => [2, 3, 4]
2.
3.list-of-obj =
4. * name: \Alice
5. age: 23
6. * name: \Betty
7. age: 26
8.
9.[..name for list-of-obj] # => ['Alice', 'Betty']

1.var i$, x$, ref$, len$, listOfObj, y$;
2.for (i$ = 0, len$ = (ref$ = [1, 2, 3]).length; i$ < len$; ++i$) {
3. x$ = ref$[i$];
4. x$ + 1;
5.}
6.listOfObj = [{
7. name: 'Alice',
8. age: 23
9.}, {
10. name: 'Betty',
11. age: 26
12.}];
13.for (i$ = 0, len$ = listOfObj.length; i$ < len$; ++i$) {
14. y$ = listOfObj[i$];
15. y$.name;
16.}

对象推导式产生对象:

1.{[key, val * 2] for key, value of {a: 1, b: 2}}
2.# => {a: 2, b: 4}

1.var key, ref$, value;
2.for (key in ref$ = {
3. a: 1,
4. b: 2
5.}) {
6. value = ref$[key];
7. [key, val * 2];
8.}

while循环:

1.i = 0
2.list = [1 to 10]
3.while n < 9
4. n = list[++i]

1.var i, list, n;
2.i = 0;
3.list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4.while (n < 9) {
5. n = list[++i];
6.}

until等价于while not

while/until同样支持when,一个可选的else语句会自动在循环体根本不会执行后自动执行。

1.i = 0
2.list = [1 to 10]
3.while n < 9
4. n = list[++i]

1.var i, list, n;
2.i = 0;
3.list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4.while (n < 9) {
5. n = list[++i];
6.}

do while循环:

1.i = 0
2.list = [1 to 10]
3.
4.do
5. i++
6.while list[i] < 9

1.var i, list;
2.i = 0;
3.list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4.do {
5. i++;
6.} while (list[i] < 9);

while循环语句中支持更新:

1.i = 0
2.list = [1 to 10]
3.
4.while list[i] < 9, i++ then i

1.var i, list;
2.i = 0;
3.list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4.for (; list[i] < 9; i++) {
5. i;
6.}

while true循环:

1.i = 0
2.loop
3. \ha
4. break if ++i > 20
5.
6.i = 0
7.for ever
8. \ha
9. if ++i > 20
10. break

1.var i;
2.i = 0;
3.for (;;) {
4. 'ha';
5. if (++i > 20) {
6. break;
7. }
8.}
9.i = 0;
10.for (;;) {
11. 'ha';
12. if (++i > 20) {
13. break;
14. }
15.}

Switch

break会被自动插入,允许多条件。

1.switch 6
2. case 1 then \hello
3. case 2, 4 then \boom
4. case 6
5. 'here it is'
6. default \something

1.switch (6) {
2. case 1:
3. 'hello';
4. break;
5. case 2:
6. case 4:
7. 'boom';
8. break;
9. case 6:
10. 'here it is';
11. break;
12. default:
13. 'something';
14.}

如果省略switch后的参数,那么默认是switch true。(翻译会等价的取反)

1.switch
2. case 5 == 6
3. \never
4. case false
5. 'also never'
6. case 6 / 2 is 3
7. \here

1.switch (false) {
2. case 5 !== 6:
3. 'never';
4. break;
5. case !false:
6. 'also never';
7. break;
8. case 6 / 2 !== 3:
9. 'here';
10.}

你可以使用fallthrough来取消自动插入breakfallthrough必须放到case块的最后,
当然switch也可以被用于表达式中。

1.result = switch 6
2. case 6
3. something = 5
4. fallthrough
5. case 4
6. 'this is it'
7.
8.result # => 'this is it'

1.var result, something;
2.result = (function() {
3. switch (6) {
4. case 6:
5. something = 5;
6. // fallthrough
7. case 4:
8. return 'this is it';
9. }
10.}());
11.result;

|case的语法糖,=>then的语法糖,| otherwise| _都是default的语法糖。

1.switch 'moto'
2.| "something" => \hello
3.| \explosion \boom => \boom
4.| <[ the moto ? ]> => 'here it is'
5.| otherwise => \something

1.switch ('moto') {
2. case "something":
3. 'hello';
4. break;
5. case 'explosion':
6. case 'boom':
7. 'boom';
8. break;
9. case 'the':
10. case 'moto':
11. case '?':
12. 'here it is';
13. break;
14. default:
15. 'something';
16.}

switch语句中可以使用that关键字:

1.switch num
2.| 2 => console.log that
3.| _ => console.log that

1.var that;
2.switch (that = num) {
3. case 2:
4. console.log(that);
5. break;
6. default:
7. console.log(that);
8.}

在箭头(如:->等),:=之后出现case,会形成隐式switch语句:

1.func = (param) ->
2. | param.length < 5 => param.length
3. | _ => param.slice 3
4.
5.func \hello # => lo
6.
7.state = | 2 + 2 is 5 => 'I love Big Brother'
8. | _ => 'I love Julia'

1.var func, state;
2.func = function(param) {
3. switch (false) {
4. case !(param.length < 5):
5. return param.length;
6. default:
7. return param.slice(3);
8. }
9.};
10.func('hello');
11.state = (function() {
12. switch (false) {
13. case 2 + 2 !== 5:
14. return 'I love Big Brother';
15. default:
16. return 'I love Julia';
17. }
18.}());

你也可以使用CoffeeScript那样风格的switch语句:

1.day = \Sun
2.switch day
3. when 'Mon' then 'go to work'
4. when 'Tue' then 'go to a movie'
5. when 'Thu' then 'go drinking'
6. when 'Fri','Sat'
7. 'go dancing'
8. when 'Sun' then 'drink more'
9. else 'go to work'

1.var day;
2.day = 'Sun';
3.switch (day) {
4. case 'Mon':
5. 'go to work';
6. break;
7. case 'Tue':
8. 'go to a movie';
9. break;
10. case 'Thu':
11. 'go drinking';
12. break;
13. case 'Fri':
14. case 'Sat':
15. 'go dancing';
16. break;
17. case 'Sun':
18. 'drink more';
19. break;
20. default:
21. 'go to work';
22.}
 

LiveScript 流程控制、循环以及列表推导式的更多相关文章

  1. Python之路-条件控制&循环语句&列表推导式&常用函数

    一.什么是条件控制语句 条件控制语句,也可以称之为判断语句,通过一条或多条的执行结果来决定接下来要执行的代码块. 二.if语句 if语句是用来进行判断的,最简答的if语句只有一个判断一个操作. 语法: ...

  2. enumerate小技巧和列表推导式

    1.enumerate enumerate函数用于遍历序列中的元素以及它们的下标,这样你就可以通过index 直接定位你的数据了. 之前对list操作的时候,即想取到下表,又想取到对应值,我是这么来实 ...

  3. python之生成器和列表推导式

    一.生成器函数 1.生成器 就是自己用python代码写的迭代器,生成器的本质就是迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现). 2.构建生成器的两种方式 1,生成 ...

  4. Python2和Python3中列表推导式的不同

    Python2和Python3中列表推导式的不同 python2 >>> x = 'my girl' >>> lst = [x for x in 'hello'] ...

  5. 迭代列表不要For循环,这是Python列表推导式最基本的概念

    如果你还在使用 For 循环迭代列表,那么你需要了解了解列表推导式,看看它的基本概念都是什么. 列表解析式(List comprehension)或者称为列表推导式,是 Python 中非常强大和优雅 ...

  6. Python: 列表推导式--轻量级循环

    定义: 列表推导式(list comprehension)是利用其他列表创建新列表的一种方法,其工作方式类似于for循环,对列表进行过滤变种操作 eg1: >>> [x*x for ...

  7. 列表推导式对比For循环执行效率

    我们在前面的学习中都知道,如果把1-10以内的元素追加到一个新的列表表中,如果使用for循环我们可以这么做: a = [] for i in range(1,11): a.append(i) prin ...

  8. python中的列表推导式——轻量级循环

    列表推导式(list comprehension)是利用其他列表创建新列表(类似于数学术语中的集合推导式)的一种方法.它的工作方式类似于for循环,也很简单. 列表推导式书写形式: [表达式 for ...

  9. python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)

    一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...

随机推荐

  1. Jenkins访问路径配置自定义的相对路径

    Jenkins安装时没有配置自定义的相对访问路径,例如配置的端口是29957,那访问路径就是http://localhost:29957.以下介绍把访问路径改成http://localhost:299 ...

  2. 爬去豆瓣图书top250数据存储到csv中

    from lxml import etree import requests import csv fp=open('C://Users/Administrator/Desktop/lianxi/do ...

  3. mininet安装,使用

    http://mininet.org/download/ http://sdnhub.cn/index.php/mininet-walkthrough-chinese/ --------------- ...

  4. UVALive 3983 Robotruck (单调队列,dp)

    如果状态定义为序号和重量的话,决策就是下一个垃圾捡或者不减,但是状态数太多了. 如果只定义序号作为状态的话,决策就变成从前面的某个j一直捡到i才送回垃圾. 这就变成了一个区间选最小值的问题,用单调队列 ...

  5. [论文理解]Region-Based Convolutional Networks for Accurate Object Detection and Segmentation

    Region-Based Convolutional Networks for Accurate Object Detection and Segmentation 概括 这是一篇2016年的目标检测 ...

  6. Python XML 解析

    什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML 是一套定义语义标记的规则,这些标记将文档分成许多部件并 ...

  7. Kubernetes之pod的属性

    属性名称 取值类型                   是否必选 取值说明 version String Required(必) 版本号,例如v1 kind String Required pod m ...

  8. kubernetes监控-prometheus(十六)

    监控方案 cAdvisor+Heapster+InfluxDB+Grafana Y 简单 容器监控 cAdvisor/exporter+Prometheus+Grafana Y 扩展性好 容器,应用, ...

  9. 前缀树,trie树

    前缀树: 假设一个字符串数组,“abcd”,"bcd","gef" , 构建一颗树,字母是在路径上,节点上最基本的存储的信息包括: 以这个节点结尾的 字符串的数 ...

  10. 【转】matlab练习程序(奇异值分解压缩图像)

    介绍一下奇异值分解来压缩图像.今年的上半年中的一篇博客贴了一篇用奇异值分解处理pca问题的程序,当时用的是图像序列,是把图像序列中的不同部分分离开来.这里是用的不是图像序列了,只是单单的一幅图像,所以 ...