亲自动手写一遍,加深印象
掌握迭代器还是蛮重要的,项目中就使用迭代器做数据管理。
练习18.1 请编写一个迭代器fromto,使得如下循环与数值型for等价,你能否以无状态迭代器实现?
练习18.2 向上一个练习中的迭代器增加一个步进的参数。你能否也用无状态迭代器实现?
for i in fromto(n,m) do
body
end
18.1 & 18.2一起回答:
--迭代器
local function iter(data,i)
local pace = data.pace or 1
i = i + pace
if data.max < i then return nil end
return i
end
--迭代器工厂 开始,结尾,步距
function fromto(n,m,p)
local data = {} --将结尾与步距打包
data.max = m
data.pace = p
local pace = data.pace or 1
return iter,data ,n - pace
end
输出结果:
练习18.3 请编写一个迭代器uniquewords,该迭代器返回指定文件中没有重复的所有单词(提示:基于示例18.1中allwords,使用一个表来存储已经处理过的所有单词)。
function uniquewords(path)
io.input(path)
local line = io.read() --当前行
local pos = 1 --当前行的当前位置
local wordList = {} --将已经找到的单词缓存在闭包中
return function() --迭代函数
while line do
local w,e = string.match(line,"(%w+)()",pos)
if w and wordList[w] == nil then
wordList[w] = 1
pos = e
return w
elseif w and not wordList[w] == nil then
pos = e
else
line = io.read()
pos = 1
end
end
return nil
end
end
输出结果:
练习18.4 请编写一个迭代器,该迭代器可以返回指定字符串的所有非空子串
function allsubstr(str)
local startIndex = 1
local endIndex = 0
local length = str and #str or 0
return function()
endIndex = endIndex + 1
if endIndex > length then
startIndex = startIndex + 1
endIndex = startIndex
end
if startIndex > length then
return nil
end
return string.sub(str,startIndex,endIndex)
end
end
输出结果:
练习18.5 请编写一个真正的迭代器,该迭代器遍历指定集合的所有子集(该迭代器可以使用同一个表来保存所有结果,只需要在每次迭代时改变表的内容即可,不需要为每个子集创建一个新表)。
--真正的迭代器
function allsubagg(list,func) --集合aggregation
local sublist = {}
table.insert(sublist,{}) --空集也是一个子集
for k,v in pairs(list) do
--第一步,拷贝一个结果集 等同于 copyResult = table.copy(sublist)
local copyResult = {}
for _,v1 in pairs(sublist) do
local subCopyResult = {}
for _,v2 in pairs(v1) do
table.insert(subCopyResult,v2)
end
table.insert(copyResult,subCopyResult)
end
--第二步,在拷贝出来的结果集copyResult中插入元素
for _,v1 in pairs(copyResult) do
table.insert(v1,v)
end
--第三步,将拷贝出来的结果集合集与原结果集合并 等同于 sublist = sublist + copyResult
for _,v1 in pairs(copyResult) do
table.insert(sublist,v1)
end
end
--执行迭代回调
for i=1,#sublist do
func(sublist[i])
end
end
--输出表格内容
function printTable(_table)
print('{'..table.concat(_table,',')..'}')
end
--测试
allsubagg({4,5,6},printTable)
输出结果
本文地址:https://blog.csdn.net/xc1313741/article/details/110904891