Project1
标题:
你真的会用数组迭代吗?
[打印本页]
作者:
六祈
时间:
2010-9-24 22:15
标题:
你真的会用数组迭代吗?
本帖最后由 六祈 于 2010-9-24 23:32 编辑
众所周知,数组最简单的迭代就是for..in..语句,包括RGSS中默认的脚本。
所以愚者想和大家分享的是,怎么样让你的迭代写的更好看~
请诸位往下看
先赋值一个数组:
arr = [1 , 2, 3, 4, 5, 6 , 7 , 8 , 9 , 10]
复制代码
这句有一种简单的写法:
arr = [*1..8]
复制代码
*表示将一个范围【Range】或者数组【Array】展开
Array#each
each方法是一切迭代的基础
任务:打印所有元素
arr.each{|e| p e}
复制代码
就可以实现
for e in arr
p e
end
复制代码
一样的功能
查看F1就可以知道,RGSS有一个内置模块叫Enumerable,定义过each方法的类混入Enumerable模块后就可以使用以下众多方法:
1、find
任务:找出arr中第一个3的倍数
x = arr.find{|e| e % 3 == 0}
复制代码
代码块的语句是一个布尔表达式,find方法会返回第一个使代码块表达式为真的元素,【detect方法是find方法的别名】
2、find_all
任务:找出arr中所有奇数
arr_x = arr.find_all{|e| e % 2 == 1}
复制代码
代码块的语句是一个布尔表达式,find_all方法会返回所有使表达式为真的元素的数组【select是find_all方法的别名,另外reject是select的反义词,收集布尔值为假的元素】
3、collect
任务:得到2、4、6、8……16这些数【即arr元素的2倍】
arr2 = arr.collect{|e| e * 2}
复制代码
代码块的语句的返回值作为新数组的元素被收集【map是collect方法的别名】
4、each_index和each_with_index
注意这两个方法与each类似,each_index迭代的参数为索引值【从0开始】,each_with_index迭代有两个参数,第一个为元素,第二个为索引
5、any?
任务:arr中是否存在一个大于10的数
exist = arr.any?{|e| e > 10}
复制代码
代码块依然是布尔表达式,只要有一个元素使其为真,就返回真【与any?类似还有一个all?方法,all?方法只有所有元素均为真时才会返回真】
6、grep
任务:只对4、5、6三个元素迭代,并分别打印它们的三倍
arr.collect{|e| e.to_s}.grep(/[456]/){|e| p(e * 3)}
复制代码
grep方法需要一个正则表达式参数,后面的代码块只迭代匹配该正则的元素,返回一个以代码块返回值为元素的数组,可以理解为一个带过滤器的collect方法。上述代码结果为打印出12,15和18,并返回一个数组,数组包含3个nil【p方法返回nil值】
7、inject
任务:计算8的阶乘【即arr中所有元素相乘】
total = arr.inject(1){|tot , e| tot *= e}
复制代码
inject方法需要一个参数,作为初始值【如果没有,则以第一个元素作为初始值,从第二个元素开始迭代】,代码块需要两个参数,第一个参数是叠加值,第二个参数是迭代的元素,迭代完成后会返回叠加值
8、sort和sort_by
任务:怎么样从一堆事件中找到x坐标与主角x坐标差最小的事件
http://rpg.blue/forum.php?mod=vi ... p;page=1#pid1529709
被迭代数组:$game_map.events.values【events是哈希,它的键是事件id,值为事件对象】
首先用sort_by方法排序【该方法会根据代码块计算结果的大小排序,小的放在前面】
sorted_events = $game_map.events.values.sort_by{|event| (event.x - $game_player.x).abs}
复制代码
ok,完成排序,然后取出sorted_events数组第一个元素就ok了
event = sorted_events[0]
复制代码
好啦~今天就先讲到这里,欢迎大家补充更多好玩的方法哟~【尤其是德斯金和purple苏大人,还有II弟】
作者:
moy
时间:
2010-9-24 22:28
咱不会用数组迭代{:nm_3:}
作者:
逸豫
时间:
2010-9-24 23:22
本帖最后由 逸豫 于 2010-9-24 23:31 编辑
arr = [1 , 2, 3, 4, 5, 6 , 7 , 8 , 9 , 10]
arr.grep(/[456]/){|e| p (e * 3)}
复制代码
Ruby 1.8.6解释器 出现警告warning: don't put space before argument parentheses
同时无输出 求解
1、p后面不需要空格
2、貌似正则表达式只匹配字符串?
作者:
禾西
时间:
2010-9-25 01:20
迭代的方法還有很多呢~有 #map #reverse_each等等,以前就秘密地發布過這東西耶~
作者:
fux2
时间:
2010-9-25 06:55
学到EACH用法了。
第一次看到6祈大人在这里发帖。
作者:
「旅」
时间:
2010-9-25 07:05
><居然没叫我来抢沙发……
支持支持~~话说我是最先听小祈酱老师讲课的~~自豪~~
作者:
小角色
时间:
2010-9-25 08:47
{:nm_9:}来膜拜各位脚本大神~
作者:
goahead
时间:
2010-9-25 10:46
提示:
作者被禁止或删除 内容自动屏蔽
作者:
紫苏
时间:
2010-9-25 10:59
讲的很好,很多方法都没用过 o.o
其实这种迭代器的思想起源自 Lisp 的抽象列表函数,比如 mapchar 这个经典 Lisp 函数就是对列表中每一个元素进行迭代,等同于 Ruby 的 each,具体的操作在编译时是抽象的,直到运行时传递了实际的 lambda 匿名函数(等同于Ruby 的块)才具象化,不过区别是 Lisp 风格的语言,其基本数据结构是链表而不是数组,所以还可以有 fold 等抽象函数进行列表结构递归的抽象化
对了,最后一个 sort_by 用来排序是很不错,但实际上如果只是想找最小值,那排序就有点浪费了,其实完全可以遍历一次数组,找出最小值,这样只需要 O(n),而排序是 O(n log n)
作者:
bbaugle
时间:
2010-9-25 12:41
不看F1的路过.........
作者:
退屈£无聊
时间:
2010-9-25 20:24
本帖最后由 退屈£无聊 于 2010-9-25 20:32 编辑
咋左看右看都觉得这贴是针对我的.?
个人连数组是什么都不知道 - -
上次问我的时候我毫不犹豫地填了一个alias - -!
啊,占楼学习.
[line]4[/line]
看完这个,泪目啊.连发新手教程的心都没有了.恩,继续钻研中 - -
虽然咱是会用FOR的- -
泪目+ 1000万不解释
作者:
紫苏
时间:
2010-9-25 23:55
……紫苏大人如何得知?【势不两立】从何而来?
六祈 发表于 2010-9-24 22:15
因为你们拿了3次 ACM 冠军(今年又是你们!),而我们只有两次(而且是很多年前的了,最近人才凋零……),所以,忌妒你~~~
作者:
九夜神尊
时间:
2010-9-28 01:42
我很好奇的问6折大人。
1:这样做会不会比较大的节省内存
2:类似定义
def ox+= (n)
xxxxx
end
祈祷你知道我说的什么,这样不行,但我想知道怎么样行。
说白了就是想alias某些地方地方的x +-*/ 法,然后我这想法是不是太天真。
泪奔一句话,6折大人说一下,能不能只是修改一下Window_Base 就实现动态窗口背景!!
作者:
六祈
时间:
2010-9-28 02:35
本帖最后由 六祈 于 2010-9-28 02:38 编辑
回复
九夜神尊
的帖子
九夜大人不必客气,愚者也只是一只新人而已
【暴走状态】愚者名为六祈,乃是六个祈愿的意思,也可以简称67【暴走结束】
1、Ruby的each是用c写的,效率不错,不过Enumerable模块是用Ruby写的,所以这一系列迭代方法的效率和手写循环是一样的【不过可以让代码好看很多很多,容易理解】
2、类似ox += xx这样的写法其实是一种语法糖,它等于在调用ox.=(ox + xx)【ox = ox + xx】事实上它调用了两个方法
def ox;end;
def ox=(ox);end;
另外测试def ox+=()方法在ruby1.8.6里报错
再另外,+之类的方法的确可以重写
3、回答无能。。。
作者:
禾西
时间:
2010-9-28 05:45
動態窗口背景……這個東西偽個Sprite就可以了。話說現在大家越來越喜歡用圖片做背景,XP的默認window skin有點糟糕,比不上VX的效果。
作者:
鼎风乱影
时间:
2011-8-12 14:32
不会啊 啊啊 啊啊啊!
ApI吗
作者:
chd114
时间:
2012-5-19 15:04
变量要怎么做
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1