lua常用操作

1 .Lua生成随机数:

Lua 生成随机数需要用到两个函数:
math.randomseed(xx), math.random([n [, m]])

1. math.randomseed(n) 接收一个整数 n 作为随机序列种子。
2. math.random([n [, m]]) 有三种用法: 无参调用, 产生 (0,1) 之间的浮点随机数; 只有参数 n, 产生 1-n 之间的整数; 有两个参数 n, m, 产生 n-m 之间的随机整数

:os.time() 返回的时间是秒级的, 不够精确, 而 random() 还有个毛病就是如果 seed 很小或者seed 变化很小,产生的随机序列很相似。

解决:把 time返回的数值字串倒过来(低位变高位), 再取高位6位。 这样, 即使 time变化很小, 但是因为低位变了高位, 种子数值变化却很大,就可以使伪随机序列生成的更好一些。

2. 

-- 在棋盘范围内,生成n个随机位置(不重复)
CHESSBOARD_MAX = 5*5
function GenRandomPos(n)
    local pos_list = {}
    local count = 0
    math.randomseed(tostring(os.time()):reverse():sub(1, 6))  
    while(count < n) do 
        local v = math.random(1, CHESSBOARD_MAX)
        local flag = false
        for j,val in pairs(pos_list) do 
            if val == v then
                flag = true
                break
            end
        end
        if not flag then
            table.insert(pos_list, v)
            count = count + 1
        end
    end
    return pos_list
end

3. 

-- 参数:待分割的字符串,分割字符
-- 返回:子串表.(含有空串)
function LuaStringSplit(str, split_char)
    local sub_str_tab = {};
    while (true) do
        local pos = string.find(str, split_char);
        if (not pos) then
            sub_str_tab[#sub_str_tab + 1] = str;
            break;
        end
        local sub_str = string.sub(str, 1, pos - 1);
        sub_str_tab[#sub_str_tab + 1] = sub_str;
        str = string.sub(str, pos + 1, #str);
    end

    return sub_str_tab;
end

4.

(1)

-- 返回当前日期数值
function GeTCurrDateMDY()
    local date_str = os.date("%x")
    local date_arr = LuaStringSplit(date_str, "/")
    local month, day, year = tonumber(date_arr[1]), tonumber(date_arr[2]), tonumber(date_arr[3])
    return month, day, year
end

(2)

local open_time_cnf = {
    {2, 2,},     -- month, day
    {4, 12,},
}
-- 判断当前日期是否在配置表的日期区间内(转换成 时间戳 进行判断)
function IsInDateRange(_open_time_cnf)
    local today = os.date("*t")
    local curr_time = os.time({month = today.month, day = today.day, year = 2015,})
    local start_time = os.time({month = _open_time_cnf[1][1], day = _open_time_cnf[1][2], year = 2015,})
    local end_time = os.time({month = _open_time_cnf[2][1], day = _open_time_cnf[2][2], year = 2015,})
    print(start_time, curr_time, end_time)
    -- os.time的参数也可以是下面这种
    -- print(os.time({day=18, month=5, year=2012, hour=0, minute=0, second=0}))
    return (start_time <= curr_time and curr_time <= end_time)
end
print(IsInDateRange(open_time_cnf))

5.

-- Lua 中删除 table 元素
local test = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p' }
local test_remove_flag = {}

function DoSomething(_table)
    for k, v in pairs( _table ) do
        -- 一般我们不在循环中删除,在循环中删除会造成一些错误。这是可以建立一个remove表用来标记将要删除的
        -- test_remove_flag[k] = (k % 2 == 0) and true or false
        -- print("------------" ,k, test_remove_flag[k])
        test_remove_flag[v] = (k % 2 == 0) and true or false
        -- dosomething
     -- v 为 列表项
_table[k] copy值
    end
end

DoSomething(test)

-- 删除标记为true的元素(从后往前删除)
-- table.remove操作后,后面的元素会往前移位,这时候后续的删除索引对应的元素已经不是之前的索引对应的元素了
for i = #test, 1, -1 do
    if test_remove_flag[test[i]] then
        table.remove(test, i)
    end
end

for j = 1, #test do
    print(test[j])
end

6. 有关lua全局变量的解析,请参见另一篇博客 lua全局变量和局部变量

-- tab不是一张lua表,或者表为空,则返回true;否则,返回false
list = {"a", "b", "c", "d",} 
function IsTableEmpty(tab)
    -- tab不是一张表
    if type(tab) ~= 'table' then 
        return true 
    end
    -- _G.next(tab) 相当于调用全局next函数遍历tab表的下一个元素
    return _G.next(tab) == nil
end 
local flag = IsTableEmpty(list) 
print(flag)
-------------------------------------------
-- false

-- 所有全局变量都会存在_G里面,_G是一个table
g_var = "global_var."     -- 全局变量
print(g_var)
print(_G.g_var)
local l_var = "local_var."         -- 局部变量
print(l_var)
print(_G.l_var)
---------------------------------------------
-- global_var.
-- global_var.
-- local_var.
-- nil
-- [Finished in 0.1s]

7. 

CnfShopYouHui =
{
    [4] = {
        name = "技能石",
    },
    [5] = {
        name = "强化石",
    },
    [6] = {
        name = "仙宠品阶丹",
    },
    [1] = {
        name = "小花束",
    },
    [2] = {
        name = "大花束",
    },
    [3] = {
        name = "豪华花束",
    },
};

local temp_cnf = CnfShopYouHui

for i, item in pairs(CnfShopYouHui) do 
    print(" ------------ > ", i, item.name)
end

-- temp_cnf 是对CnfShopYouHui的一个引用,修改team_cnf会导致CnfShopYouHui也被修改
table.remove(temp_cnf, 1)
print(" ********************************** ")

for i, item in pairs(CnfShopYouHui) do 
    print(" ------------ > ", i,  item.name)
end

-- output

 ------------ >     6    仙宠品阶丹
 ------------ >     2    大花束
 ------------ >     3    豪华花束
 ------------ >     1    小花束
 ------------ >     4    技能石
 ------------ >     5    强化石
 ********************************** 
 ------------ >     2    豪华花束
 ------------ >     3    技能石
 ------------ >     1    大花束
 ------------ >     4    强化石
 ------------ >     5    仙宠品阶丹
[Finished in 0.1s]

8.

CnfShopYouHui =
{
    [4] = {
        name = "技能石",
    },
    [5] = {
        name = "强化石",
    },
    [6] = {
        name = "仙宠品阶丹",
    },
    [1] = {
        name = "小花束",
    },
    [2] = {
        name = "大花束",
    },
    [3] = {
        name = "豪华花束",
    },
};

for i, item in pairs(CnfShopYouHui) do
    if 1 == i then 
        table.remove(CnfShopYouHui, 1)
        CnfShopYouHui[i] = nil
    end
    -- i, item 是CnfShopYouHui内容项的(值)复制,CnfShopYouHui[i]是内容项本身的(引用)
    -- 所以,虽然上面删除了table.remove(CnfShopYouHui, 1), 但此时item已经复制了它的值。
    print(" ------------ > ", i, item.name, CnfShopYouHui[i])
end

-- output

 ------------ >     6    仙宠品阶丹    table: 004FC270
 ------------ >     2    大花束    table: 004FC310
 ------------ >     3    豪华花束    table: 004FC360
 ------------ >     1    小花束    nil
 ------------ >     4    强化石    table: 004FC220
 ------------ >     5    仙宠品阶丹    table: 004FC270
[Finished in 0.1s]

10.

--*************************************************--
-- 树形打印table成员(table, variable, function ……)
local tablePrinted = {}
function printTableItem(k, v, tab)
    for i = 1, tab do
        io.write("    ")    -- 缩进
    end
    io.write(tostring(k), " = ", tostring(v), "
")
    if type(v) == "table" then
        if not tablePrinted[v] then
            tablePrinted[v] = true
            for k, v in pairs(v) do
                -- tab 非局部变量(Upvalue)                  
                printTableItem(k, v, tab + 1)
            end
        end
    end
end

--*************************************************--
 -- lfs(Lua file system, lfs.dll 动态库), 在lua的安装目录下就有此动态库
 -- D:5.1clibs
require "lfs"  
-- 打印当前文件路径
print("-- lfs.currentdir() -------------------------------------------- ")
print(lfs.currentdir())

print("-- printTableItem lfs -------------------------------------------- ")
-- 查看lfs.dll动态库 成员
printTableItem("lfs", lfs, 0)
-- -- 打印全局表_G
-- -- printTableItem("_G", _G, 0)

local  file_name = "D:/tes.lua" -- D:	es.lua (绝对路径和相对路径)
local t = lfs.attributes(file_name)     -- 取文件全部属性
print("-- lfs.attributes D:/tes.lua -------------------------------------------- ")
for k, data in pairs(t) do
    print(tostring(k))
end

print("-- modify_time -------------------------------------------- ")
local modify_time = lfs.attributes(file_name, "modification")     -- 取文件一个属性
print(tostring(modify_time))

print(" END -------------------------------------------- ")
-- output
-- lfs.currentdir() -------------------------------------------- 
D:
-- printTableItem lfs -------------------------------------------- 
lfs = table: 004EB518
    symlinkattributes = function: 004ECF28
    dir = function: 004ECE28
    _VERSION = LuaFileSystem 1.4.2
    setmode = function: 004ECF48
    unlock = function: 004ECFC8
    _DESCRIPTION = LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution
    currentdir = function: 004ECE08
    _COPYRIGHT = Copyright (C) 2003 Kepler Project
    attributes = function: 004ECDA8
    lock = function: 004ECE68
    touch = function: 004ECF88
    mkdir = function: 004ECEA8
    chdir = function: 004ECDC8
    rmdir = function: 004ECEE8
-- lfs.attributes D:/tes.lua -------------------------------------------- 
dev
change
access
rdev
nlink
uid
gid
ino
mode
modification
size
-- modify_time -------------------------------------------- 
1426498014
 END -------------------------------------------- 
[Finished in 0.2s]

11. lua脚本热加载

(1)首先在D:路径下创建以下三个文件:

-- D:add.lua

function add_func()
    local x, y = 12, 32
    print(">>>>>>>>>>>>>>add_func(12, 32):x+y = " .. tostring(x+y))
end
add_func()
-- D:dive.lua

function dive_func()
    local x, y = 12, 3
    print(">>>>>>>>>>>>>>dive_func(12, 3):x / y = " .. tostring(x/y))
end
dive_func()
-- D:hotreload.lua

--*************************************************--
SCRIPTLIST = 
{
    "add",
    "dive",
}
----[[
-- 实现lua脚本的热加载
pre_modify_time = 0 -- 模拟原始改变时间
function HotReload(name_str)
    if name_str then
        local module_name = name_str
        print(" >>>>>>>>>>>>>> name_str", name_str)
        package.loaded[module_name] = nil
        require(module_name)
    else
        require "lfs"
        print(lfs.currentdir()) -- D:
        for _, module_name in pairs(SCRIPTLIST) do
            local file_name = lfs.currentdir() .. module_name .. ".lua"
            local modify_time = lfs.attributes(file_name, "modification")
            print("file_name, pre_modify_time, modify_time", file_name, pre_modify_time, modify_time)
            if modify_time > pre_modify_time then
                package.loaded[module_name] = nil
                require(module_name)
            end
        end
    end
end
--]]
HotReload()

(2)执行hotreload.lua文件,输出如下:

D:
file_name, pre_modify_time, modify_time    D:add.lua    0    1426502029
>>>>>>>>>>>>>>add_func(12, 32):x+y = 44
file_name, pre_modify_time, modify_time    D:dive.lua    0    1426502032
>>>>>>>>>>>>>>dive_func(12, 3):x / y = 4
[Finished in 0.2s]

12.

-- lua赋值操作中,如果赋值table是采用引用方式赋值;(userdata等类型还未检验)
-- 如果赋值常规变量(string,number,...等类型)则采用值传递方式赋值。
local a, b = 31, 42
local copy_a = a
local change_b = b
change_b = change_b + 1
print(" ---------------- a, copy_a = ", a, copy_a)
print(" ---------------- b, change_b = ", b, change_b)

local str = "test_str"
local change_str = str
change_str = change_str .. "_add_str"
print(" ---------------- str, change_str = ", str, change_str)

-- table
local t = {"a", "b", "d", "e",}
local change_t = t
table.remove(change_t, 1)
for i, v in pairs(t) do
    print(" -------------- ", v)
end

-- function
local add = function(x, y)
    print(" ----------- add(x, y) = ", x + y)
end
local dive = add
dive = function(x, y)
    print(" ----------- dive(x, y) = ", x/y)
end
add(12, 3)
dive(12, 3)

-- output

 ---------------- a, copy_a =     31    31
 ---------------- b, change_b =     42    43
 ---------------- str, change_str =     test_str    test_str_add_str
 --------------     b
 --------------     d
 --------------     e
 ----------- add(x, y) =     15
 ----------- dive(x, y) =     4
[Finished in 0.1s]

13.

local test_str = "my_test_str" 
local testt =
{    
    list = {"a", "b", "c", "d",list_1 = {"e", "f", "g",},},
    limit_value=31,
    limit_type=1,
    list_t = list,
    list_tt = testt,
    list_ttt = limit_value,
    list_tttt = test_str,
}
print(" >>>>>>>>>>>>>>>>> testt.list_ttt, testt.limit_value, testt.list_tttt = ", testt.list_ttt, testt.limit_value, testt.list_tttt)
-- 注:由于在表testt内定义list_ttt的时候,表testt还没定义结束,此时limit_value为nil,所以list_ttt输出为nil;
-- 而test_str在表testt之前定义完成,所以可以在表testt内对字段list_tttt赋值;
-- 同时,当打印testt.limit_value时,表testt和表内字段都已经定义完成。
-------------------------------------------------------------------------

-- ipairs 和 pairs 的lua的table遍历的区别
print(" >>>>>>>>>>>>>>>>> ipairs")
for j, item in ipairs(testt) do
    print(j)
end
print(" >>>>>>>>>>>>>>>>> pairs")
for j, item in pairs(testt) do
    print(j)
end

-- 取表长度# 原理和 (i)pairs 一样,table.sort 也类似,等等。
print(" ---------------- #testt", tostring(#testt))
-- lua中取table长度操作(#table_name)是基于Array的table
local list_l = {"a", "b", "c", "d",}     
print(" ---------------- #list_l", tostring(#list_l))
-------------------------------------------------------------------------

-- foreach遍历整张table, #list_k只打印符合array(以 1 开始的连续整数作为key的table)的连续下标的值
local list_k = {aa = "a", bb = "b", [2] = "c", [3] = "d", [4] = "e", [5] = "f",}     
local list_k_2 = {aa = "a", bb = "b", "c", "d", [4] = "e", [5] = "f",}     
table.foreach(list_k, function(i, v)
        print(" ---------------- i, v = ", i, v)
    end)
print(" ---------------- #list_k = ", tostring(#list_k))
print(" ---------------- #list_k_2 = ", tostring(#list_k_2))

-- output

 >>>>>>>>>>>>>>>>> testt.list_ttt, testt.limit_value, testt.list_tttt =     nil    31    my_test_str
 >>>>>>>>>>>>>>>>> ipairs
 >>>>>>>>>>>>>>>>> pairs
limit_value
list
list_tttt
limit_type
 ---------------- #testt    0
 ---------------- #list_l    4
 ---------------- i, v =     2    c
 ---------------- i, v =     aa    a
 ---------------- i, v =     3    d
 ---------------- i, v =     4    e
 ---------------- i, v =     5    f
 ---------------- i, v =     bb    b
 ---------------- #list_k =     0
 ---------------- #list_k_2 =     2
[Finished in 0.1s]


14.

function table.isArray(tab)
    if not tab then
        return false
    end

    local ret = true
    local idx = 1
    for f, v in pairs(tab) do
        if type(f) == "number" then
            if f ~= idx then
                ret = false
            end
        else
            ret = false
        end
        if not ret then break end
        idx = idx + 1
    end
    return ret
end


-- table序列化 serialize
--序列化一个Table
function serialize(t)
    local assign={}

    local function table2str(t, parent)
        local ret = {}

        if table.isArray(t) then
            table.foreach(t, function(i, v)
                local k = tostring(i)
                local dotkey = parent.."["..k.."]"
                local t = type(v)
                if t == "userdata" or t == "function" or t == "thread" or t == "proto" or t == "upval" then
                    --ignore
                elseif t == "table" then
                    table.insert(ret, table2str(v, dotkey))
                elseif t == "string" then
                    table.insert(ret, string.format("%q", v))
                elseif t == "number" then
                    if v == math.huge then
                        table.insert(ret, "math.huge")
                    elseif v == -math.huge then
                        table.insert(ret, "-math.huge")
                    else
                        table.insert(ret,  tostring(v))
                    end
                else
                    table.insert(ret,  tostring(v))
                end
            end)
        else                
            table.foreach(t, function(f, v)

                local k = type(f)=="number" and "["..f.."]" or f
                local dotkey = parent..(type(f)=="number" and k or "."..k)
                local t = type(v)
                if t == "userdata" or t == "function" or t == "thread" or t == "proto" or t == "upval" then
                    --ignore
                elseif t == "table" then
                    table.insert(ret, string.format("%s=%s", k, table2str(v, dotkey)))
                elseif t == "string" then
                    table.insert(ret, string.format("%s=%q", k, v))
                elseif t == "number" then
                    if v == math.huge then
                        table.insert(ret, string.format("%s=%s", k, "math.huge"))
                    elseif v == -math.huge then
                        table.insert(ret, string.format("%s=%s", k, "-math.huge"))
                    else
                        table.insert(ret, string.format("%s=%s", k, tostring(v)))
                    end
                else
                    table.insert(ret, string.format("%s=%s", k, tostring(v)))
                end
            end)
        end
        -- table.concat 遍历ret并使用","分隔元素
        return "{"..table.concat(ret,",").."}"
    end

    if type(t) == "table" then     -- 调用table2str入口
        return string.format("%s",  table2str(t,"_"))
    else
        return tostring(t)
    end
end 

local testt =
{    
    limit_value=31,
    limit_type=1,
    list = {"a", "b", "c", "d",list_1 = {"e", "f", "g",}, list_2 = testt,},
    my_list_1 = {"111", "222", "333", "4444", "555",},
}
print(serialize(testt))

-- output

{limit_value=31,my_list_1={"111","222","333","4444","555"},list={[1]="a",[2]="b",[3]="c",[4]="d",list_1={"e","f","g"}},limit_type=1}
[Finished in 0.2s]

 15.

GameConfig = {}
GameConfig.ResCompose = {}
GameConfig.ResCompose.Effects_E612 =
{
    Path = "resource/language/gt/effects/e612.png",
    ScaleSize = 0.5,
    FrameInterval = 0.125,
    
    
    [1] = { 1494, 0, 228, 151, 3, 4, },
    
    [2] = { 660, 0, 284, 244, 1, -85, },
    
    [3] = { 336, 0, 323, 249, 0, -82, },
    
    -- [4] = { 0, 0, 335, 250, 2, -81, },
    
    [5] = { 1226, 0, 267, 240, -2, -91, },
    
    [6] = { 945, 0, 280, 242, -3, -87, },
}
print(" >>>>>>>>>>>>>>>>>>>>> 1")
-- table.getn(table_name) 获取table_name中连续id的元素个数
print(table.getn(GameConfig.ResCompose.Effects_E612)) -- 3
print(" >>>>>>>>>>>>>>>>>>>>> 2")

 16.文件操作

-- 打开文件读取
function OpenFile(path)
    local content = ""
    local file = io.open(path, "r")
    if (not file) then
        -- 打开失败
        return nil
    end

    for line in file:lines() do
        content = content .. line .. "
"
    end
    file:close(path)
    return content

    -- 写入文件
    -- local file = io.open(path, "w")
    -- file:write(content)
    -- file:close()
end
-- 调用
-- local str = OpenFile("luafiletest.txt")

-- 重命名文件
function ChangeFileName(path)
    local status = ""
    local file = io.open(path, "r")
    file:close(path)     

    -- 关闭之后才能重命名
    local status = os.rename(path, path..".bak")
    if (not status) then
        -- 重命名失败
        return
    end
    return status
end
-- local status = ChangeFileName("luafiletest.txt")

 17.字符串和数字比较

18.

-- 将字符串转成table
function stringToTable(str)  
   local ret = loadstring("return "..str)()  
   return ret  
end 

str = "{1}, print('run print')"  
local test = stringToTable(str)  
for i, v in pairs(test) do
    print(i, v)
end

local str_s = "print('test print')"
print(str_s)
原文地址:https://www.cnblogs.com/yyxt/p/4180596.html