快速掌握Lua 5.3 —— "table"库

Q:如何向”table”中插入和删除元素?

A:之前提到的,向”table”中插入元素使用索引的方式,而删除’table”中的元素则是将其赋为nil。这里介绍的是”table”库中提供的插入与删除函数,

--[[ table.insert(list, [pos,] value)
     向表"list""pos"位置插入值"value"。
     list[pos], list[pos+1], ···, list[#list]这些元素向后顺移,
     pos默认是"#list+1",也就是默认会在"list"的末尾插入元素。

     table.remove(list [, pos])
     删除表"list""pos"位置的元素,并返回删除的元素。
     list[pos+1], list[pos+2], ···, list[#list]这些元素向前顺移,
     pos默认是"#list",也就是默认删除"list"末尾的元素。]]

function print_array(t)
    for i, v in pairs(t) do
        io.write(v .. ", ")
    end
    io.write("\n")
end

a = {10, 20, 30}
print_array(a)    --> 10, 20, 30,
table.insert(a, 1, 15)
print_array(a)    --> 15, 10, 20, 30
table.insert(a, 35)
print_array(a)    --> 15, 10, 20, 30, 35, -- 默认在末尾插入
print(table.remove(a, 3))    --> 20
print_array(a)    --> 15, 10, 30, 35, 
print(table.remove(a))    --> 35
print_array(a)    --> 15, 10, 30, -- 默认删除末尾元素

Q:如何排序”table”中的元素?

A:

--[[ table.sort(list [, comp])
     使用函数"comp"排序表"list"中的元素。
     "comp"接收两个列表内元素作为参数,
     当第一个元素需要排在第二个元素之前时,返回"true",否则返回"false"。
     如果没有提供"comp",默认使用"<"(小于 操作符)比对元素。]]

function print_array(t)
    for i, v in pairs(t) do
        io.write(v .. ", ")
    end 
    io.write("\n")  
end 

a = {17, 33, 29}
table.sort(a, function (v2, v1) -- 根据个位数字的大小,由小到大排序。
    return v2 % 10 < v1 % 10
end)
print_array(a)    --> 33, 17, 29,
table.sort(a)    -- comp不指定,默认按照数值大小,由小到大排序。
print_array(a)    --> 17, 29, 33, 

Q:如何拼接”table”中的元素?

A:

--[[ table.concat(list [, sep [, i [, j]]])
     将表"list"中从整数元素"i"到整数元素"j"之间的所有元素拼接在一起,分隔符为"sep""sep"默认为空字符串,"i"默认为1"j"默认为"#list",
     所以默认将表"list"中从1开始连续的整数索引元素拼接在一起,无分隔符。]]
t = {"12", 34, [8] = "56", m="78", n=90}
print(table.concat(t))    --> 1234 -- 数字34自动转换为字符串"34"进行拼接。
print(table.concat(t, "*"))    --> 12*34
print(table.concat(t, "*", 2, 2))    --> 34

Q:如何将”table”中的整数索引元素快速复制到另一个”table”中?

A:

--[[ table.move (a1, f, e, t [,a2]) 将表"a1"中从整数索引"f"到整数索引"e"之间(源区间)的元素 复制到表"a2"中整数索引"t"及之后的位置(目标区间), 表"a2"默认为"a1",目标区间与源区间可以重叠。]]
t = {"12", 34, [8] = "56", m="78", n=90}
t1 = {}
table.move(t, 1, 8, 3, t1)
print("t: ")
for i,v in pairs(t) do print(i, v) end
print("t1: ")
for i,v in pairs(t1) do print(i, v) end
--[[ result: t: 1 12 2 34 8 56 n 90 m 78 t1: 4 34 10 56 3 12]]

附加:

1、有了table.insert()table.remove(),实现栈就很容易。”push()”相当于table.insert(a, v),”pop()”相当于table.remove(a)
2、”table”的”key”的顺序并不固定,

lines = {
    luaH_set = 10,
    luaH_get = 24,
    luaH_present = 48,
}

for i, v in pairs(lines) do
    print(i)    --> 每次的结果都不相同。
end

“table”的”key”也无法直接排序,如果一定要排序,需要将这些”key”拷贝到一个另”table”中,并排序新的”table”,

-- 继续使用上面的"lines"。

a = {}
for i in pairs(lines) do table.insert(a, i) end
table.sort(a)    -- 使用默认排序方式,按照了字符串的排序规则排序。
for i, v in pairs(a) do print(v) end
--[[ result: luaH_get luaH_present luaH_set]]

-- 还可以使用"iterator"的方式实现。
function pairsByKeys (t, f)
    local a = {}
    for n in pairs(t) do table.insert(a, n) end
    table.sort(a, f)
    local i = 0      -- iterator variable
    local iter = function ()   -- iterator function
        i = i + 1
        if a[i] == nil then return nil
        else return a[i], t[a[i]]
        end
    end
    return iter
end

for name, line in pairsByKeys(lines) do
    print(name, line)
end
--[[ result: luaH_get 24 luaH_present 48 luaH_set 10]]

3、

--[[ table.pack(···) 创建一个"table",并将参数作为元素以整数索引(1, 2, ...)插入"table"中。 并将"n"这个域存储参数的总个数,返回所创建的"table"。]]
t = table.pack(5, 9, 11)
for i, v in pairs(lines) do print(i, v) end
--[[ result: 1 5 2 9 3 11 n 3]]

--[[ table.unpack(list [, i [, j]])
     返回表"list"中从索引"i"到索引"j"的元素。
     "i"默认为1"j"默认为"#list"。所以默认返回表"list"中的所有元素。
     注意,"i""j"都是整数,所以只能返回表"list"中的整数索引元素。]]
print(table.unpack(t, 2, 3))    --> 9 11
-- 默认返回所有整数索引元素,域"n"不会被返回。
print(table.unpack(t))    --> 5 9 11

感觉table.pack()table.unpack()的用处不大,他们都被限定为只能操作整数索引的元素,而一个”table”中经常不仅仅只有整数索引的元素。
此外,创建并初始化”table”使用索引的方式更加灵活;而遍历”table”中的元素更多的是使用pairs(),即使是只遍历整数索引的元素,ipairs()也能够很好的胜任。

你可能感兴趣的:(lua)