zoukankan      html  css  js  c++  java
  • LiveScript 流程控制、循环以及列表推导式

    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 ar
    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 ] 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 oom
    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. ever
    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 oom => oom
    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.}
     
  • 相关阅读:
    概率论与统计学---笔记
    实用概率论与数理统计学--笔记
    并发编程总结5-JUC-REENTRANTLOCK-3(非公平锁)
    并发编程总结4-JUC-REENTRANTLOCK-2(公平锁)
    并发编程总结3——JUC-LOCK-1
    DOCKER & SWARM1.2
    Docker
    hdfs命令
    并发编程总结2——java线程基础2
    并发编程总结1——java线程基础1
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/5177703.html
Copyright © 2011-2022 走看看