LiveScript 流程控制、循环以及列表推导式
The LiveScript Book
The LiveScript Book
Generators and Yield
你可以在你的 LiveScript 代码中使用 Ecmascript 2015 中的的generators
和yield
了!
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
,对我们已经有的各种箭头,依然可以正常工作。
yield
跟 javascript 中的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
。
when
(case,|
的语法糖)是一个可选的循环守护。
如果把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)
,
再一次几乎所有的都是可选的。let
,by
和when
跟前面讲的还是一样的。
VAL-VAR
是当前列表项的值,INDEX-VAR
是VAL-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)
又一次机会都是可选的,let
和when
跟前面的一样。
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
来取消自动插入break
,fallthrough
必须放到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 流程控制、循环以及列表推导式的更多相关文章
- Python之路-条件控制&循环语句&列表推导式&常用函数
一.什么是条件控制语句 条件控制语句,也可以称之为判断语句,通过一条或多条的执行结果来决定接下来要执行的代码块. 二.if语句 if语句是用来进行判断的,最简答的if语句只有一个判断一个操作. 语法: ...
- enumerate小技巧和列表推导式
1.enumerate enumerate函数用于遍历序列中的元素以及它们的下标,这样你就可以通过index 直接定位你的数据了. 之前对list操作的时候,即想取到下表,又想取到对应值,我是这么来实 ...
- python之生成器和列表推导式
一.生成器函数 1.生成器 就是自己用python代码写的迭代器,生成器的本质就是迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现). 2.构建生成器的两种方式 1,生成 ...
- Python2和Python3中列表推导式的不同
Python2和Python3中列表推导式的不同 python2 >>> x = 'my girl' >>> lst = [x for x in 'hello'] ...
- 迭代列表不要For循环,这是Python列表推导式最基本的概念
如果你还在使用 For 循环迭代列表,那么你需要了解了解列表推导式,看看它的基本概念都是什么. 列表解析式(List comprehension)或者称为列表推导式,是 Python 中非常强大和优雅 ...
- Python: 列表推导式--轻量级循环
定义: 列表推导式(list comprehension)是利用其他列表创建新列表的一种方法,其工作方式类似于for循环,对列表进行过滤变种操作 eg1: >>> [x*x for ...
- 列表推导式对比For循环执行效率
我们在前面的学习中都知道,如果把1-10以内的元素追加到一个新的列表表中,如果使用for循环我们可以这么做: a = [] for i in range(1,11): a.append(i) prin ...
- python中的列表推导式——轻量级循环
列表推导式(list comprehension)是利用其他列表创建新列表(类似于数学术语中的集合推导式)的一种方法.它的工作方式类似于for循环,也很简单. 列表推导式书写形式: [表达式 for ...
- python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)
一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...
随机推荐
- Java集合框架—Set
集合框架 Set的特点:无序,不可以重复元素. (1)HashSet:数据结构是哈希表.线程是非同步的. 保证元素唯一性的原理:判断元素的hashCode值是否相同. ...
- Volley解析(一)--Volley的使用
Volley解析(一)--Volley的使用 Volley 是一个HTTP协议的网络请求框架 Volley的优势: 自动安排网络请求 支持多个并发网络连接 具有标准HTTP缓存一致性的透明磁盘和内存响 ...
- mac不限速下载百度网盘
本文转载自:https://blog.csdn.net/u010837612/article/details/80029212 相信大家都比较困惑,百度网盘客户端限速后一般只有几十K的下载速度,Win ...
- sqlserver创建触发器
Create TRIGGER [dbo].[tr_Delete_AllocationedDN] --删除指定账户已分配未拣货的任务 ON [dbo].[FRU_PickLocationNew] --触 ...
- (转)SQL注入攻击简介
如果你是做Javaweb应用开发的,那么必须熟悉那声名狼藉的SQL注入式攻击.去年Sony就遭受了SQL注入攻击,被盗用了一些Sony play station(PS机)用户的数据.在SQL注入攻击里 ...
- BZOJ 4896 :[Thu Summer Camp2016]补退选 Trie树+Vector
4896: [Thu Summer Camp2016]补退选 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 315 Solved: 97[Submi ...
- GWTDesigner_v5.1.0破解码
GWTDesigner_v5.1.0_win32_x86.exe破解码,双击运行keygeno.jar,然后输入用户名.网卡MAC,然后单击Generate,将生成的文件放在C:\Documents ...
- kubernetes-深入理解pod对象(七)
Pod中如何管理多个容器 Pod中可以同时运行多个进程(作为容器运行)协同工作.同一个Pod中的容器会自动的分配到同一个 node 上.同一个Pod中的容器共享资源.网络环境和依赖,它们总是被同时调度 ...
- SC || Chapter 5 复习向
可复用性 ┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉ 行为子结构 对于父子的继承关系的要求: ·子类可以增加方法,但不可以删 ·子类需实现抽象类型中未实现的方法 ·子类重写(override)的方法必须 ...
- mysql crash cource 书中实例
样例表 CREATE TABLE customers( cust_id int NOT NULL AUTO_INCREMENT, cust_name char(50) ...