table列表库

table 库提供操作table对象的函数. table对象可以用来创建各种复杂的数据结构

一、table数据类型简介

什么是table:

table是LAScript最重要的数据类型,可以存储复杂的数据结构。
table可以存储任意多个元素,每个元素都是一个“键值对”。“键”可以是字符或其他附nil以外的数据类型,甚至可以在table元素中包含table,table允许嵌套。

通常把“键”放在索引操作符“[]”中来索引一个元素的值,这时候键又称为“下标”。例如 tab["键"] tab[1] ;
也可以把一个符合变量命名规则的键放在成员操作符“.”后面,这时候键又称为“公用成员”。例如 tab.key tab.key2 ;
什么是table字典:
table中的所有元素都是键值对,table本身就是一个“字典(Dictionaries)”.在某些语言中可能称为“映射(Map)”、“联合内存(associative memories)”或“联合数组(associative arrays)”,字典的是无序的键值对(key:value pairs )集合,键是互不相同的(在同一个字典之内)。
什么是table数组:
字典中所有以数字索引作为键的元素构成数组。数组是有序的

更多关于table对象的内容请参考: 类据类型 - table;

二、table字典操作

在table字典中操作很简单,不需要任何复杂的技术.

tab = {}; -- 用花括号构造器轻松创建table字典
 
tab["abc"] = 120; --轻松添加一个键值对
tab[1] = "数组元素"--轻松添加一个键值对
tab.name = "我是一个字符串"; ----轻松添加一个键值对
 
tab.abc = nil; --赋值为nil即删除一个键值对
 
win.consoleOpen();
--遍历table字典中的所有元素
for k,v in pairs(tab) do  
    print(k,v);
end;

三、table数组操作

1、数组大小

table.maxn (tab)

获取table类型参数tab的数组大小,示例:

tab = {};--创建空的数组
tab[1000] = 0; --初始化数组大小
 
n=table.maxn(tab);
win.messageBox("数组大小"..n);
?

2、在数组中插入删除元素

table.insert (tab, [pos,] value)
在table类型参数tab中插入元素(value),
pos指定插入位置,如果指定这个参数,table.insert首先在tab[pos]插入value并将后面的所有元素顺序向后移动。
如果省略pos参数,则使用默认值table.maxn (tab)+1; 也就是在数组最后面添加元素,这样就不用移动其他元素。

value = table.remove (tab [, pos])
在数组中指定位置的删除元素,并返回这个元素,并向前移动后面的全部元素,并且数组的大小改变。不带位置参数调用的时候,他删除array的最后一个元素。

如果您不希望在删除无素后改变其他的元素的位置,可以使用赋值为nil的方法删除一个元素

tab = {"a","b","c","d","e"}
table.remove (tab ,2); --移除第二个元素,后面的元素全部向前移动一个单位.
tab[2] = nil; --删除第二个元素,不会改变其他元素的位置。

如果不指定位置参数,
table.insert (tab, value) 在数组顶端压入一个元素(类似栈的push操作)。
value = table.remove (tab) 在数组顶部弹出一个元素(类似栈的pop操作)。
这样就实现了元素后进先出的“栈”。不需要任何复杂的技术,用table就可以很容易的实现高效的“栈”

如果我们需要在table的开始端插入移除元素,可以用:
table.insert(tab,1,value);删除元素用value = table.remove(tab,1);
但是这样需要不断的来回移动所有的元素,并不是最好的办法(对于小的数组也许不需要考虑效率的问题)。
当然我们还有更好的方法,请参考: 数据结构 - 用table实现队列、双端队列

3、遍历数组

方法一:

用for循环顺序遍历所有元素。

win.consoleOpen();--打开控制台窗口,用来支持print函数
tab = {"字符串", 123,"字符串2",23,56,78,99,123,0,test=123};--tab.test不是数组元素
 
for i=1,table.maxn(tab),1    do
    if( tab[i] )then --对于稀疏数组这个判断是必要的
        print(i,tab[i])
    end;
end;
 

上面的方法对于稀疏数组是低效的。想象一下对下面这样的数组使用上面介绍的for循环。

tab = {};
tab[10000000] = 0;
--数组只有一个元素却要循环10000000次

所以大多时候,我们推荐下面的方法(速度更快)

方法二:

用泛型for循环遍历数组元素。

win.consoleOpen();--打开控制台窗口,用来支持print函数
tab = {"字符串", 123,"字符串2",23,56,78,99,123,0,test=123};--tab.test不是数组元素

for i,v in ipairs(tab) do
    --i为键,v是匹配的值,在这里键值对有序的出现。
    print(i,v); -->显示: 数字索引,数组元素的值
end;

比较上面两种方法的效率:

win.consoleOpen();--打开控制台窗口,用来支持print函数
 
tab = {};
tab[10000000] = 0;
 
t = os.tick()
 
for i=1,table.maxn(tab),1    do
    if( tab[i] )then --对于稀疏数组这个判断是必要的
        print(i,tab[i])
    end;
end;
 
print("for递增循环耗时",os.tick() - t); -->显示2172毫秒
 
t = os.tick()
 
for i,v in ipairs(tab) do  
   print(i,v);
end;
 
print("for循环耗时",os.tick() - t); -->显示0毫秒

方法三:

next函数通常用在「fap模拟程序」中「周而复始」的循环遍历table对象,
请参考链接: next函数

4、数组排序

table.sort (tab [, comProc])

comProc = function(a,b)
      return a < b;
end;

对数组tab重新排序,comProc是一个可选参数,comProc是一个排序回调函数用于比较两个元素的大小。
table.sort在排序过程中,每遇到两个元素就调用comProc函数比较大小,并将两个元素作为参数传递给comProc函数。
如果comProc函数认为第一个参数比较小返回true,如果认为第二个参数比较小应当返回false。
如果没有提供排序回调函数,table.sort默认调用小于操作符比较两个元素的大小。

请看下面的例子:

win.consoleOpen();
 
tab ={3,4,7,8,6,5,2,1}
table.sort(tab);
 
--看看排序后的结果
for i,v in ipairs(tab) do
    print(i,v)-->显示 1 2 3 4 5 6 7 8
end;

--  ----------------------------------------------
--table.sort会调用这个函数比较元素大小
comProc = function(a,b)
    return a > b ;--反过来排序
end;
 
table.sort(tab,comProc);
 
--看看排序后的结果
for i,v in ipairs(tab) do
    print(i,v)-->显示 8 7 6 5 4 3 2 1
end;

table.sort是对数组的值域进行排序,不能对字典排序,也不能对键域(下标域)进行排序。

如果我们需要对字典进行排序,可以自已写一个迭代器。将字典中的数据复制到一个数组中然后进行排序。
下面我们介绍如何对table中的键域进行排序.

--支持table中的键域排序,参数tab为table对象,f为排序回调函数(可省略)
function kpairs (tab, f)
     --泛型for开始循环以前调用这个函数创建一个闭包
     local tarr = {}
--字典中的数据复制到一个数组中然后进行排序
     for k in pairs(tab) do table.insert(tarr, k) end
     table.sort(tarr, f);--调用默认的排序函数f对字典中的键进行排序
 
     local i = 0-- 迭代器计数器.(在闭包中保存值)
 
     local iter = function ()     -- 迭代函数
          i = i + 1
          if(not tarr[i])then
               return nil
          else
               return tarr[i], tab[tarr[i]]
          end
     end
     return iter; --返回一个迭代函数给泛型for;
end
 
tab ={c=2,d=2,e=2,g=2,h=2,a=1,b=1,f=1,i=1,j=1,k=9};
 
win.consoleOpen();
for k,v in kpairs(tab) do   
   print(k,v); --table中的键按字母顺序排序了
end;

下一节内容table库进阶