• 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)
  • 相关阅读:
    通过日期获取星期几,通过日期获取凌晨、上午、中午、下午、晚上
    asp.net 格式化显示时间为几个月,几天前,几小时前,几分钟前,或几秒前
    继承和多态 复习
    .net 缩略图 宽高比 .js缩略图 宽高比
    显示实现接口和实现接口的区别
    HDMI信号解析
    锂电池充电过程
    HDMI接口基础知识及硬件设计
    HDMI传输原理:TMDS
    为什么有些信号线串接33R小电阻?
  • 原文地址:https://www.cnblogs.com/yyxt/p/4180596.html
Copyright © 2020-2023  润新知