本文会以vector / map / set 这三种数据类型的角度来梳理 table 支持的不同遍历方式。

table as std::vector

一般,C/C++中的 array / vector (下文简称 vector) 是没有 key。但是在 lua 中使用了 table 这种通用结构,就引入了 key 的问题。

在这里,把想用做 vector 的 table,做一个非常重要的约定:1 初始,key 连续。由于 table 的自由度很高,这个需要开发者自己约束。

---- 新建

t = {"A", "BB", "CCC"} -- 默认的key就是1初始且连续

-- 或者
t = {} -- 建立一个空的
t[1] = 1
t[2] = 2
t[3] = 3 -- 或者
t = {
[1] = 1,
[2] = 2,
[3] = 3, -- 这里逗号可有可无
}

  

---- 模拟 pushback

vector = {}
function vector.pushback(vec, val)
vec[#vec + 1] = val
end v = {}
vector.pushback(v, 1)
vector.pushback(v, 2)
vector.pushback(v, 3)

  

---- 遍历,使用 ipairs,按照key从1开始,从小到大返回元素。

for key, value in ipairs(v) do
print(key, value)
end

 

table as std::map 用key寻值,无重复。 通用情况

---- 新建

m = {["A"] = 1, ["BB"] = 2, ["CCC"] = 3}
m = {["A"] = 1, ["BB"] = "string2", 10 = 3} -- key 和 value 的数据类型不必相同,自由伴随着控制的难度,一定程度上,key 和 value 推荐使用相同的类型。value 也可以是 table。handle 这种情况需要注意更多。 -- 或者
m = {} -- 建立一个空的
m[1] = 1
m[2] = 2
m["3"] = 3 -- 打印结果和 3 一样,可以通过 type 判断类型差别。详见后续例子 -- 或者
m = {
[1] = 1,
[2] = 2,
["3"] = 3, -- 这里逗号可有可无
}

  

---- 模拟 insert,不会重复插入

map = {}
function map.insert(map, key, val)
map[key] = val
end m = {["A"] = "str1"}
map.insert(m, 1, 25)
map.insert(m, "1", 5)
map.insert(m, 1, 2)
map.insert(m, 1, 25)

---- 查询元素,有就是1,没有就是0

function map.have(map, key)
if map[key] == nil then
return false
else
return true
end
end m = {["A"] = "str1"}
map.insert(m, 1, 25)
map.insert(m, "1", 5)
map.insert(m, 1, 2)
map.insert(m, 1, 25) print(map.have(m, "A"))
print(map.have(m, A)) ------- 结果 --------
true
false

  

----遍历,使用 pairs(),按照 key 的 harsh 值大小排序输出。注意,顺序这个概念在 map 中并不重要

for key, value in pairs(m) do
print(key, type(key), value, type(value))
end

  

table as std::map 特殊情况:key 为数字,但不连续,希望从小到大遍历,或相反。

使用迭代器(自定义的)

-- from: program in Lua
function pairsByKeys(t)
local a = {}
for n in pairs(t) do
a[#a + 1] = n
end
table.sort(a) -- 默认升序
  -- table.sort(a, function(a1, a2) return a1 > a2 end) -- 降序
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end

  

完整示例:

map = {}
function map.insert(map, key, val)
map[key] = val
end function map.have(map, key)
if map[key] == nil then
return false
else
return true
end
end -- from: program in Lua
function pairsByKeys(t)
local a = {}
for n in pairs(t) do
a[#a + 1] = n
end
table.sort(a)
local i = 0
return function ()
i = i + 1
return a[i], t[a[i]]
end
end m = {}
map.insert(m, 1, 10)
map.insert(m, 3, 30)
map.insert(m, 9, 90)
map.insert(m, 5, 50) print("pairsByKeys")
for key, value in pairsByKeys(m) do
print(key, value)
end print("pairs")
for key, value in pairs(m) do
print(key, value)
end ----------- 结果 ------------
pairsByKeys
1 10
3 30
5 50
9 90
pairs
1 10
9 90
5 50
3 30

  

table as std::set 有序、不重复

这里的 map 和 set 的差别就是在插入的时候,需要对所有数据按照 key 排序,从小到大。在lua 里,map 已经没有重复的 key。

---- 新建

s = {}
s = {1,2,3}
s = {"A", "B", "C"} --> 字符串排序的规则需要自己定义

---- 模拟 insert,需要指定 value 的比较方式。set 是升序排列的,key 值不可改(注意赋值方式),所以需要指定 value 的比较方式。

set = {}
function set.insert(_s, val, _f) -- _f 就是需要自定义的比较函数,作为外部参数输入。详见后续
_s[#_s + 1] = val
if #_s > 1 then
table.sort(_s, _f)
end
end

---- 判断元素有无

set = {}
function set.have(s, key)
if s[key] == nil then
return false
else
return true
end
end

---- 迭代所有元素使用:ipairs()

for key, value in ipairs(s) do
print(key, value)
end

---- 完整示例  

set = {}
function set.insert(_s, val, _f)
_s[#_s + 1] = val
if #_s > 1 then
table.sort(_s, _f)
end
end function set.have(s, key)
if s[key] == nil then
return false
else
return true
end
end -- you need to define a function to sort values in ascending order.
function f(currenyVal, nextVal)
return currenyVal < nextVal -- number
end s = {}
set.insert(s, 1, f)
set.insert(s, 3, f)
set.insert(s, 9, f)
set.insert(s, 5, f) print(set.have(s, 10)) -- 判断有无
print(set.have(s, 1)) for key, value in ipairs(s) do
print(key, value)
end

  

table as linked lists

请参考:https://www.lua.org/pil/11.3.html

table as queues (队列,先进先出,不做介绍,请参考原文)

请参考:https://www.lua.org/pil/11.4.html

参考

http://blog.51cto.com/rangercyh/1032925

https://www.lua.org/pil/11.html

lua 4 使用table实现其他数据结构,并介绍遍历方法的更多相关文章

  1. Lua中使用table实现的其它5种数据结构

    Lua中使用table实现的其它5种数据结构 lua中的table不是一种简单的数据结构,它可以作为其他数据结构的基础,如:数组,记录,链表,队列等都可以用它来表示. 1.数组 在lua中,table ...

  2. Lua 学习笔记(十)数据结构

    在Lua中的table不是一种简单的数据结构,它可以作为其他数据结构的基础.其他语言提供的数据结构,如数组.记录.线性表.队列.集合等,在Lua中都可以通过table来表示.而且使用Lua实现这些数据 ...

  3. Lua表(table)的用法_个人总结

    Lua表(table)的用法_个人总结 1.表的创建及表的介绍 --table 是lua的一种数据结构用来帮助我们创建不同的数据类型.如:数组和字典--lua table 使用关联型数组,你可以用任意 ...

  4. 递归打印lua中的table

    在lua中,table是比较常用的数据形式,有时候为了打印出里面的内容,需要做一些特殊处理. 废话不多讲,直接粘代码: print = release_print -- 递归打印table local ...

  5. [Lua]弱引用table

    参考链接: http://www.benmutou.com/archives/1808 一.强引用table lua中的table是引用类型,更准确地说,是强引用类型.如下第二段代码,在内存中有一个{ ...

  6. Lua中的table函数库

    table.concat(table, sep,  start, end) concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组 ...

  7. Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)

    0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似“北京 ...

  8. Lua表(table)的个人总结

    1.表的简介和构造 table是个很强大且神奇的东西,又可以作为数组和字典,又可以当作对象,设置module.它是由数组和哈希表结合的实现的.他的key可以是除nil以外任意类型的值,key为整数时, ...

  9. Step By Step(Lua弱引用table)

    Step By Step(Lua弱引用table) Lua采用了基于垃圾收集的内存管理机制,因此对于程序员来说,在很多时候内存问题都将不再困扰他们.然而任何垃圾收集器都不是万能的,在有些特殊情况下,垃 ...

随机推荐

  1. MongoDB学习笔记(四、MongoDB安全管理)

    目录: mongoDB角色 mongoDB初始化账号 mongoDB安全认证 其它常用的命令 mongoDB角色: mongoDB初始化账号: 1.启动mongoDB ./mongod -f mong ...

  2. acwing 600. 仰视奶牛

    题目地址  https://www.acwing.com/problem/content/description/602/ 约翰有N头奶牛,编号为1到N. 现在这N头奶牛按编号从小到大的顺序站成了一排 ...

  3. 洛谷 P4017 最大食物链计数

    洛谷 P4017 最大食物链计数 洛谷传送门 题目背景 你知道食物链吗?Delia生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条.于是她来就来求助你,然而你也不会啊!写 ...

  4. mysql和oracle分页

    mysql分页 关键字limit,limit m,n 其中m表示起始位置的下标,下标从0开始.n表示要显示的条数,比如要查询一个表的第2到5条数据. ,; oracle分页 关键字rownum, ro ...

  5. iOS: 线程中那些常见的锁

    一.介绍 在多线程开发中,锁的使用基本必不可少,主要是为了解决资源共享时出现争夺而导致数据不一致的问题,也就是线程安全问题.锁的种类很多,在实际开发中,需要根据情况选择性的选取使用,毕竟使用锁也是消耗 ...

  6. Redis缓存雪崩,缓存穿透,热点key解决方案和分析

    缓存穿透 缓存系统,按照KEY去查询VALUE,当KEY对应的VALUE一定不存在的时候并对KEY并发请求量很大的时候,就会对后端造成很大的压力. (查询一个必然不存在的数据.比如文章表,查询一个不存 ...

  7. Protractor - 环境设置

    去年出于好奇搭建过一个Protractor+Cucumber的测试框架,当时项目上并没有用到AngularJS,所以框架能运行起来之后没有再深入了.最近新项目引入了AngularJS,想起去年搭的那个 ...

  8. 自己实现LinkedList

    public class MyLinkedList<E> { private Node first; private int size; public int size(){ return ...

  9. 在 .NET Core 下使用 SixLabors.ImageSharp 操作图片文件(放大、缩小、裁剪、加水印等等)的几个小示例

    1. 基础 1.1  将图片的宽度和高度缩小一半 直接贴代码了: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup ...

  10. bootstrap 自定义模态窗口

    $(".classname").click(function () { $('#mymodel').modal('show'); alert('模态框打开了'); }); $('# ...