• 新浪微博:
  • 微信 :
按键精灵电脑版
立即下载

软件版本:2014.06
软件大小:22.9M
更新时间:03-18

按键精灵安卓版
立即下载

软件版本:3.3.8
软件大小:62.5M
更新时间:12-18

按键精灵iOS版
立即下载

软件版本:1.7.1
软件大小:29.2M
更新时间:06-22

最新企业版UiBot
立即下载

软件版本:3.3
软件大小:282M
更新时间:08-06

快捷导航

登录 后使用快捷导航
没有帐号? 注册

登录 注册
发新话题 回复该主题

果壳lua教程(第二集):利用迭代器计算表中元素最大值 [复制链接]

1#


>先看代码:


  1. function table_max(t)

  2. local max = 0

  3. for key,value in pairs(t) do

  4. print(key.."="..value)

  5. if max < value Then

  6. max = value

  7. end

  8. end

  9. tb1 = {50,100,20}

  10. print(table_max(tb1))
复制代码

>我们先来看创建表和函数调用的部分:


  1. tbl={50,100,20}

  2. print(table_max(tbl))
复制代码

>首先定义了一个表,该表有3个元素分别是50,100和20,有同学问,"表"是什么玩艺儿?去年买的?当然不是!

表呢是由一组"键值对"组成,问题来了,啥叫"键值对"? 好比某人和某人很般配,天生是一对那样,"键值对"就是由"键"和"值"组成的一对"情侣"。

问题又来了:啥叫"键"?啥叫"值"?

"jian"呢就是(很贱?NO~NO~)一个key咯,key是啥?钥匙呗,有钥匙就必然会有对应的锁,那么通过一把钥匙打开一把锁,这个过程呢就是取值的过程:通过键取出了值。

打个比方,假设在一个名为tbl的表中,key是1的键,1是key的值,那么如何开锁呢?只需 print(tbl.key)一下,便能开锁——输出1了!

那么,在上述例子中:tbl={50,100,20},tbl中的三个元素到底是键呢还是值呢?对了,不是说好了表中每个元素皆由"键值对"构成的吗,怎么硬生生把人家“情侣”拆散了?

答案是:50、100和20皆为值!

小明同学提问了:那键去哪里了?

键呢被默认化了……换句话讲,如果未指定键名,则键由整数型数字(从1开始索引)分别与每个元素绑定!

小茗同学:那么,1绑定了50,2绑定了100,3绑定了20 ,老师对吗?

完全正确!但是我们也可以指定键,如:tbl={[1]=50,[2]=100,[3]=20},或 tbl={a=50,b=100,c=20},前者的访问方式是tbl[1],后者的访问方式是tbl["a"],或tbl.a

以上两种访问方式都能取出50这个值哟!大家可以下载个luaEditor编程器,自己亲自体验下!无论是风景还是人生,没有身临其境、亲历亲为,又怎能说得上真正领略过、玩味过了呢?敲代码也是如此!

接下来的代码通过print(table_max(tbl))来实现求表中最大值的函数的调用——返回并输出最大值!

那么就让我们将目光转向table_max函数吧!!!

该函数首先用一个参数变量t来接收一个表(也就是刚才我们传过去的tbl咯),然后我们来看下函数体的第一行 local max=0 啥意思——小茗又问了。

不就是像按键那样用dim 定义了一个局部变量max,并将它赋初值为0嘛!

是的!lua声明变量用的是local,而不是dim —— 重要的事,我只说一遍过!

接下来是一个for循环,在循环表达式中通过key和value这两个变量来接收 pairs函数返回的t表的每对键值,这个效果(或者说这个功能)叫做迭代器~

通过不断的迭代,每次迭代取出一对键值!

小茗同学:咋取出哒?

且看,pairs是一个迭代函数,每次迭代时(或者理解为每次循环时)都会返回两个值,一个是键名,一个是键值,分别用key和value这两变量接收!

然后通过print输出每对键值 print(key,"=",value)

再然后,要办正事了:


  1. if max < value then

  2. max = value

  3. end
复制代码

>如果max初值为0,那么首次循环时,0是否小于第一个表元素值呢(也就是50)

小茗同学:当然小于!

很好!那么第一轮循环时,max就拿到了50这个值:max = 50

第二轮循环来了,此时max=50,那么50是否小于第二次迭代时取出的值100呢?当然小于,于是max=100

第三轮循环时,max中的100不再小于第三个迭代取出的值20,所以没有发生max=20,注意,没有发生max=20 (有点重要的事情有时我会说上两遍!)

最后,通过return返回max值——也就是最大值100了!

不茗同学:这个简单的取最大值算法我以前学按键时就会了!

是的没错,但请留心:本次教程重点学的是如何用lua来实现这个算法,并且,我们还学习了表的创建和构成、pairs迭代函数,见识到了for循环所构成的迭代器效果,以及lua天生自带的多返回值效果,爽了个歪歪不是?

不茗同学:嗯、嗯,好爽!

好了,本次教程结束,大家细细品味,代码要多敲,才能敲出感情,编程嘛就是要有感情色彩,才能编织出美丽的程序世界!


### lua教程:元表的定义与运用(第二集) ###


>老规矩,先是代码:


  1. tbl1 = {1, 2, 3}

  2. tbl2 = {4, 5, 6}

  3. mt={}

  4. setmetatable(tbl1, mt)

  5. function mt._add(a,b)

  6. local result = 0

  7. for i=1,#a do

  8. result = result + a

  9. end

  10. for i=1,#b do

  11. result = result + b

  12. end

  13. return result

  14. end

  15. print(tbl1 + tbl2)
复制代码

>小茗,今天我们来讲元表。

元表就是定义表的触发事件

比如呐mt.__add(a,b),定义的就是两个表(本例为tbl1、tbl2),当发生用“+”号相加时所触发的事件:tbl1+tbl2

那么在本例中,通过+号触发了什么事件呢?

这便是mt.__add元素中所自定义的方法。

小茗同学:啥方法?实现啥功能?

如图所示,该方法实现的功能便是:将所传递过来的两个表中的所有元素进行相加,返回总和:print(tbl1+tbl2)

小茗同学:可是可是,当tbl1和tbl2这两个表通过"+"相加时,我并没有看到mt.__add函数被调用啊?

问得好!这就是元表的奇妙之处!实事上,__add是内置在lua中用于标识元方法的字段,只要通过"+"号就能实现mt.__add函数的调用了!

小茗同学:那么mt是啥?

mt可以理解为一个可以自定义的函数名,而mt之后的.__add则是关键字段(不可自定义)

小茗同学:也就是说,通过一个简单的"+"号,并且在+号左右两边分别带上一个表,就能实现自定义的加法行为?

是的没错!当然,除了加法行为外,我们还可以定义减法行为、乘法行为和除法行为哟!

小茗同学:那么顺便说说其余几个运算符的行为吧!

可以啊!减法行为用__sub定义,乘法行为用__mul定义,除法行为用__div定义!

小茗同学:那么我猜,要触发上述行为,就只需要用我们通常熟悉的-号、*号和除号,对吗老师?

是滴是滴!这有点像c++里的运算符重载(当然不明白什么是运算重载的同学不必着急,咱们接着往下看)

其实呢,上述行为或方法,我们统称为元方法,我们再来捋一捋逻辑(常言道,逻辑一捋通,一通则百通)

小茗同学:那就,捋一捋吧!

首先,上述的元方法,如mt.__add(a,b),都是有两个参数哒,分别接受两个表,在本例中第一个传进的表为tbl1(表中含有1、2、3三个元素),第二个传进的表为tbl2(表中含有4、5、6三个元素),那么这两个表传进去后搞了什么事情呢?首先定义了一个局部变量result,用于存储计算总和,并赋初值为0,其次通过两个for循环,分别对这两个表进行遍历,将每个表中的元素进行相加,并存储计算结果到result中,最后函数返回result

于是,重点来了——接下来只需通过print(tbl1+tbl2)就能输出一个结果:21

小茗同学:哇噢,我理解了,这21便是两个表中所有元素相加的结果!

唔~悟性不错!

小茗同学:那么请问mt={}是啥意思,还有setmetatable(tbl1,mt)又是怎么理解?

问得好!mt就是metatable的缩写,只是一个变量名,mt={}表示建立了一个空的新表,该表的名字叫mt

setmetatable(tbl1,mt)表示将tbl1这个普通表升级为一个名为mt的元表!

小茗同学:这么说来,元表就是普通表的升级版本?

对极了!要想升级一个普通表,使之成为元表,就必须通过setmetatable()函数来升级哟,该函数有两参数,第一参数为普通表的名称,第二参数为元表名称!

只有通过setmetatable()定义的元表(本例为mt),才能使用该元表的名称(mt)来定义运算符方法,本例为mt.__add(a,b)

小茗同学:那么如果我用local ok=tbl1+tbl2,然后再用print(ok),能否输出21?

当然可以!

小茗同学:我懂啦!那么,可以下课了吗!

当然可以!


最后编辑果壳王子 最后编辑于 2020-03-31 22:30:33
本主题由 按键合作伙伴 果壳王子 于 2020/3/31 22:29:29 执行 设置高亮 操作
果壳学院 ● 疯狂编程 QQ交流群: 327610461 (编程要从娃娃抓起)

  果壳热编程教育网:www.guokeHOT.com ←点击登录,即刻学习!

发新话题 回复该主题