List.Generate(initial as function, condition as function, next as function,optional selector as nullable function)as list
第1参数是初始函数赋值,通常使用()=>;第2个参数是对应第1参数赋值的条件函数,在条件不符合时停止循环,如果条件设置错误会导致无限循环;第3参数是根据之前的初始及条件继而运行的函数;第4参数是可选的指定输出函数,也就是对当前步骤的初始赋值进行计算;返回的是结果是列表格式。
例:
List.Generate(()=>1,
each _<3,
each _+1)
={1,2}
解释:初始赋值公式使用()=>格式,第2参数是对赋值的数据进行判断是否小于3,如果符合在赋值数据基础上+1作为新的赋值进行循环。蓝色代表赋值(初始赋值和计算结果赋值),红色代表是否满足循环终止条件。
第一步:先用公式赋值1,判断1<3,结果是True,参与第3参数计算1+1=2
第二步:用上一步的第3参数计算结果2作为赋值,判断2<3,结果是True,参与第3参数计算2+1=3
第三步:用上一步的第3参数计算结果3作为赋值,判断3<3,结果是False,循环结束返回所有赋值过的数据(包含初始赋值,不包含最后一个不符合条件的赋值)组成列表,也就是{1,2},其中1就是初始赋值。
List.Generate(()=>1,
each _<3,
each _+1,
each _*2)
={2,4}
解释:这里再前面一样公式的基础上,加上了第4参数,第4参数也是个函数,也同样可以计算,是对输出结果的再一步计算。
List.Generate(()=>{2,0},
each_{1}<3,
each{_{0}+2,_{1}+1},
each _{0})
={2,4,6}
解释:目标结果为从2开始,循环3次并返回结果。初始赋值公式使用()=>,这里赋值的是1个具有2项的列表,列表中的第1项初始赋值为2,是作为数值计算的初始值,列表中的第2项初始赋值为0,是做循环累计数。
第一步:
第1参数 | 第2参数 | 第3参数 | 第4参数 |
---|---|---|---|
{2,0} | 0<3=True | {2+2,0+1}={4,1} | 2 |
初始赋值为1个列表{2,0},判断列表的第2项,也就是0<3,结果是True则计算第3参数,计算公式为列表的第1项+2,列表的第2项+1,返回的结果是{2+2,0+1}={4,1}作为第二步的赋值,随后通过第4函数对赋值再次计算,因为初始赋值为{2,0},第4参数为返回赋值列表{2,0}的第1项,也就是2作为结果。
第二步:
第1参数 | 第2参数 | 第3参数 | 第4参数 |
---|---|---|---|
{4,1} | 1<3=True | {4+2,1+1}={6,2} | 4 |
上一步第3公式的计算结果为{4,1},也就是第2步的赋值为{4,1},判断列表的第2项,也就是1<3,结果是True,返回结果是赋值列表的第1项+2,列表的第2项+1,也就是{4+2,1+1}={6,2},第4参数作为返回赋值列表的第1项,也就是{4,1}的第1项4作为结果。
第三步:
第1参数 | 第2参数 | 第3参数 | 第4参数 |
---|---|---|---|
{6,2} | 2<3=True | {6+2,2+1}={8,3} | 6 |
上一步第3公式的计算结果为{6,2},也就是第3步的赋值为{6,2},判断列表的第2项,也就是2<3,结果是True,返回结果是赋值列表的第1项+2,列表的第2项+1,也就是{6+2,2+1}={8,3},第4参数作为返回赋值列表的第1项,也就是{6,2}的第1项6作为结果。
第四步:
第1参数 | 第2参数 | 第3参数 | 第4参数 |
---|---|---|---|
{8,3} | 3<3=False | 结束循环 | 结束循环 |
上一步第3公式的计算结果为{8,3},也就是第3步的赋值为{8,3},判断列表的第2项,也就是3<3,结果是False,终止循环,返回之前的结果作为一个列表,也就是之前的最终结果{2,4,6}
我们可以举一个实例:如果一个股票现在价格是10元,目标价格是100元,需要连续多少次涨停才能达到?最终的涨停价格是多少?
涨停次数:
List.Count(
List.Generate(()=>{10,1},
each _{0}<100,
each {_{0}*1.1, _{1}+1}))
=25
List.Last(
List.Generate(()=>{10,1},
each_{0}<100,
each {_{0}*1.1, _{1}+1},
each _{1}))
=25
解释:
第一种方式是生成一个由2个列表项组成的复合列表组合,第1项为价格,第2项为次数。因为循环终止是在100元以内即终止,所以价格肯定未能达到100,还需继续+1次才能达到目标价格,但是列表的返回值包含了原始的价格10元,所以正好抵消次数的要求。
第二种方式是因为初始赋值已经为1,列表的第2项是起循环累计的功能,所以直接取最后一次循环的列表第2项即可。所以我们在循环的时候就已经对展示结果做了指定的输出,也就是第4参数返回的结果是循环次数,最终我们取循环次数累计值的最后一个,也是25。
最终涨停价格:
List.Last(
List.Generate(()=>{10,1},
each_{0}<100,
each {_{0}*1.1, _{1}+1},
each _{0}),1)*1.1
= 108.35
解释:
因为我们考虑到循环终止时还是处于100元以下,所以如果要达到100元的目标值,还需要继续加1次涨停,同理在循环的时候我们取列表的金额,在最后一次循环金额的基础上再做一次涨停价格计算。当然这里忽略小数点的保留进位问题,因为通常情况下,涨停并不是完全是10%。有时候还会有9.97%之类的。
除此之外我们还可以用Record来记录,Record相对于List的优势在于可以对于数据进行标题命名,同样以上面的例子来看。
涨停次数:
List.Count(
List.Generate(()=>[价格=10,次数=1],
each [价格]<100,
each [价格=[价格]*1.1, 次数=[次数]+1]))
=25
List.Last(
List.Generate(()=>[价格=10,次数=1],
each [价格]<100,
each [价格=[价格]*1.1, 次数=[次数]+1],
each [次数]))
=25
逻辑都是一样,只不过用记录的话是不是更能让人理解些呢?