lua学习笔记---3.table

523 阅读3分钟

表的构造式:{}

列表风格:数组

  • 元素的访问:表名[下标],下标从1开始
  • 求长度#:
    • 如果下标为1的元素为nil,则长度为0
  • 特点:
    • 长度可变,类型可以不相同的结构
    • 没有初始化或者赋值的元素默认为nil
    • table底层实现就是数组和哈希表
    • 表示一种引用类型,一个表用另一个表赋值,表示指向同一张表
    • Lua的内存回收机制是通过GC(垃圾回收机制(标记清除法))进行回收
local tb = {1, 2, 3, 4, 5} -- 初始化
tb = {6, 7, 8, 9, 10}   -- 重新创建表
tb[6] = 11 -- 添加元素
tb[8] = 13
print(tb[7])    --nil
print(#tb)      --8
local tb1 = {[1] = 0, [2] =22, [3] = 33, [5] = 66}
print(#tb1)
-- 二位数组
local tb2 = {{1, 2, 3}, {4, 5, 6}}
print(tb2[2][3])    -- 6

记录风格:键值对(哈希表)

  • 初始化:{键名 = 值}
  • 元素的访问:
    • 表名["键名"]
    • 表名.键(推荐使用这种方式)
local size = {w = 100, h = 200}
print(size.w, size.h)

size.l = 1-- 添加元素
print(size.l)

size.getArea = function() -- 给size添加求面积的方法
    return size.w * size.h
end
--另外一种形式
-- function size.getArea()
--     return size.w * size.h
-- end
-- 求周长
size.getC = function()
    return (size.w + size.h) * 2
end
function size.getC()
    return (size.w + size.h) * 2
end
print(size.getC())

混合风格:列表和记录风格的混合

  • 求长度#:只能求数组部分长度
local tb3 = {"x", "y", x = 1, y = 2, z = 3}
print(#tb3)             --2
print(tb3[tb3.x])       --"x"
print(tb3[tb3[tb3.x]])  --1
print(tb3[3])           --nil
print("-------------")
local tb = {1, 2, 3, 4, 5}
--  遍历
for i = 1,#tb do
    print(tb[i])
end

遍历记录风格-->泛型for

泛型for:

-- for 变量1,变量2 in 表达式1,表达式2,表达式3 do
--      循环体
-- end

ipairs和pairs都会返回三个值,对应泛型for的三个表达式

  • 区别:
    • ipairs遇到元素值为nil则停止循环,pairs遇到nil继续循环
    • ipairs只能遍历table的数组部分,pairs可以变量数组和键值对部分(顺序不一定和书写的顺序一致)

实现table的拷贝

local tb4 = {"x", "y", nil, x = 1, y = 2, z = 3, "z"}
-- 赋值一个tb4的表到tbCopy
local tbCopy = {}
-- ipairs
for k,v in ipairs(tb4) do 
    print(k, v)
end
print("-------------")
-- pairs
for k,v in pairs(tb4) do
    tbCopy[k] = v   --用值给对应的键赋值
    print(k, v)
end

print("-------------")
for k,v in pairs(tbCopy) do
    print(k, v)
end

例题

local tb = {1, {x = 2}, "hello"}
print(#tb)      -- 3
print(tb[2])    -- 地址
print(#tb[2])   -- 0

local tb = {1,"x",x = {1, 2, y = 2}}
print(#tb)          -- 2
print(tb[3])        -- nil
print(#tb[tb[2]])   -- 2
-- 访问y  两种写法
print(tb["x"]["y"])
print(tb.x.y)
print(tb.x[2])  -- 访问x中的2值

local tb = {1, 2}
local tb2 = tb
tb2[1] = 11
print(tb[1])    -- 11

-- 计数器功能:
local tb = {1, 2, 2, 1, 4, 5, 6, 7, 4, 8, 10, 10, 1, 2}
local counter = {}
counter.size = #tb  --添加size键值
for i = 1, 10 do
    counter[i] = 0
end
for i =  1, #tb do
    counter[tb[i]] = counter[tb[i]] + 1
end
print("----------------")
for k,v in ipairs(counter) do
    print(k, v)
end
print("----------------")

table函数

insert:插入元素(后面的元素往后移)

  • 参数:1.表 2.下标位置(可不传,默认为最后一个) 3.值
  • 返回值:没有返回值
local tb = {1, 2, 3}
table.insert(tb, 4)

remove:移出元素(后面的元素往前移)

  • 参数:1.表 2.下标位置(可不传,默认为最后一个)
  • 返回值:删除元素的值
print(table.remove(tb))

遍历table中的所有方法

for k,v in pairs(table) do
    print(k, v)
end

例题

--删除tb表中的所有偶数
local tb = {1, 2, 2, 3, 4, 4}

-- 从前往后删
local i = 1
while i <= #tb do
    if tb[i] %2 == 0 then
        table.remove(tb, i)
    else
        i = i + 1
    end
end

--从后往前删
for i = #tb,1,-1 do
    if tb[i] % 2 == 0 then
        table.remove(tb, i)
    end
end

for i = 1,#tb do
    print(tb[i])
end