lua 数组

数组 Table Array

table 是 Lua 中唯一的数据结构,其他语言所提供的数据结构,如:arrays、records、
lists、 queues、 sets 等,Lua 都是通过 table 来实现

在 lua 中通过整数下标访问 table 中元素,即是数组。并且数组大小不固定,可动态
增长。
数组是有序的对象的装置,它可以是包含含有多个行和列的行或多维阵列的集合的单
个二维数组。

一维数组

一维数组可以用一个简单的表结构来表示,可以初始化,使用一个简单的 for 循环读取。
如下例子所示。

-- 定义一维数组
a = {1, 2, 3, 4, 5}

-- 读取数组元素
for i = 1, #a do
    print(a[i])
end

二维数组

二维数组可以用一个包含多个表的表结构来表示,可以初始化,使用两个 for 循环读取。

-- 定义二维数组
b = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
}


-- 读取二维数组元素
for i = 1, #b do
    for j = 1, #b[i] do
        print(b[i][j])
    end
end

for i, v in ipairs(b) do
    for j, w in ipairs(v) do
        print(w)
    end
end

table->array 库

# 运算符

运算符用于获取数组的长度。

a = {1, 2, 3, 4, 5}
print(#a) -- 5

拼接数组

table.concat 函数用于拼接数组。

table.concat(table, sep, start, end)
table: 要被拼接的数组或表。
sep (可选): 一个字符串,用于指定连接各个元素之间的分隔符。默认值是一个空字符串,即不使用任何分隔符。
start (可选): 指定开始拼接的索引,默认为 1end (可选): 指定结束拼接的索引,默认为表的最后一个元素。

特点
高效性: table.concat 在拼接大量元素时通常比使用简单的字符串拼接方式更高效。
支持范围拼接: 你可以选择拼接表中的部分元素,这在某些情况下非常有用。
灵活性: 可以通过选择不同的分隔符,灵活控制拼接后的字符串格式。

注意事项
table.concat 只能用于一维数组,不能直接用于包含嵌套表的多维数组。如果需要处理多维数组,你需要手动遍历每个表,然后使用 table.concat。
如果所拼接的表是空的,table.concat 的返回值将是一个空字符串。

local fruits = {"apple", "banana", "cherry"}
local result = table.concat(fruits)
print(result)  -- 输出: applebananacherry


local fruits = {"apple", "banana", "cherry"}
local result = table.concat(fruits, ", ")
print(result)  -- 输出: apple, banana, cherry

local numbers = {1, 2, 3, 4, 5}
local result = table.concat(numbers, "-", 2, 4)
print(result)  -- 输出: 2-3-4


table.sort排序数组

table.sort 是 Lua 中用于对表(数组)进行排序的函数。它的基本作用是将一个一维数组中的元素按指定的顺序进行排序。以下是对 table.sort 的详细介绍。

table.sort(table, comp)
table: 需要排序的数组(表)。
comp (可选): 一个函数,用于自定义排序的规则。如果没有提供该函数,默认为升序排序。

默认排序
如果不提供比较函数,table.sort会按照元素的自然顺序进行排。
对于数字,默认是升序排序;对于字符串则是按照字母表的顺序排序。

local numbers = {5, 2, 8, 1, 4}
table.sort(numbers)
for _, v in ipairs(numbers) do
    print(v)  -- 输出: 1, 2, 4, 5, 8
end

自定义排序

你可以提供一个自定义的比较函数来控制排序的行为。
比较函数接收两个参数,应该返回 true 或 false,以便确定它们的顺序。

local names = {"Alice", "Bob", "Charlie"}
-- 自定义一个比较函数,使其按字符串长度排序
table.sort(names, function(a, b)
    return #a < #b
end)
for _, v in ipairs(names) do
    print(v)  -- 输出: Bob, Alice, Charlie
end

只有一维数组(表)能使用 table.sort。

table.sort 是原地排序,这意味着它会直接改变传入的表,而不是返回一个新的排序表。

table.insert 插入元素

table.insert(table, [position,] value)
table: 要插入元素的目标数组或表。
position (可选): 插入元素的位置索引。如果指定,新的元素会插入到该位置,后面的元素会依次向后移动。如果不指定,默认会将元素追加到表的末尾。
value: 要插入的值或元素。

将元素插入到表的末尾

local fruits = {"apple", "banana"}
table.insert(fruits, "cherry")  -- 在表的末尾插入元素
for _, v in ipairs(fruits) do
    print(v)  -- 输出: apple, banana, cherry
end

将元素插入到指定位置

local fruits = {"apple", "banana"}
table.insert(fruits, 2, "cherry")  -- 在索引2的位置插入元素
for _, v in ipairs(fruits) do
    print(v)  -- 输出: apple, cherry, banana
end

插入多个元素(实现方式)

虽然 table.insert 只能一次插入一个元素,但可以通过循环来插入多个元素

local fruits = {"apple", "banana"}
local moreFruits = {"cherry", "date", "fig"}

for _, fruit in ipairs(moreFruits) do
    table.insert(fruits, fruit)  -- 将每个新元素插入到表的末尾
end

for _, v in ipairs(fruits) do
    print(v)  -- 输出: apple, banana, cherry, date, fig
end

table.insert 是原地操作,它直接改变传入的表,而不是返回一个新的表。

如果插入的索引超出表的当前长度,Lua 会自动在表的末尾插入这个元素。

如果插入的位置是负数,Lua 会将这个位置视为从表尾开始计算的索引。

打包 table.pack

table.pack 是 Lua 中用于将多个参数打包成一个表(table)元素的函数。这个函数在需要将多个值放在一个表中时非常有用,尤其是在处理可变数量的参数时。

table.pack(...)
...: 表示可变参数,允许传入任意数量的参数。

主要特性

打包参数: table.pack 可以接收一个或多个参数,并将其打包到一个表中。

包含元素数量: 生成的表会有一个 n 字段,表示实际元素的数量。这在进行遍历和索引时特别有用。

local packed = table.pack(1, 2, 3, "apple", "banana")
for i = 1, packed.n do
    print(packed[i])  -- 输出: 1, 2, 3, apple, banana
end
table.pack 将多个参数打包成一个表 packed,并通过 packed.n 获取元素数量。


local packed = table.pack()
print(packed.n)  -- 输出: 0
当没有传入任何参数时,table.pack 会返回一个空表,并且 n 的值为 0local packed = table.pack(1, nil, 3)
for i = 1, packed.n do
    print(packed[i])  -- 输出: 1, nil, 3
end
table.pack 可以打包 nil 值,但仍然会将 n 设置为实际参数的数量,包括 nil

使用场景

用户自定义函数的参数收集: 可用于函数接收不定数量的参数,并将它们打包成表。

数据传输: 在某些情况下,将多个值打包成表以便传递和处理会更便捷。

注意事项

使用 table.pack 时,如果需要访问返回表的元素,应该通过 packed.n 来获取元素数量,并在遍历时使用有效的索引。

table.pack 返回的表是一个普通表,可以像其他表一样使用。

解包 table.unpack

table.unpack 是 Lua 中用于将表(table)中的元素解包(提取)为多个参数的函数。这个函数非常有用,在需要将表中的值作为多个独立参数传递给函数时,特别方便。

table.unpack(table, [start], [end])
table: 要解包的表。
start (可选): 开始解包的索引,默认为 1end (可选): 结束解包的索引,默认为表的长度。

主要特性
提取表的元素: 将指定范围内的元素解包为独立的参数。
灵活的索引范围: 允许指定解包的起始和结束索引,以控制提取的元素范围。

local fruits = {"apple", "banana", "cherry"}
local a, b, c = table.unpack(fruits)

print(a)  -- 输出: apple
print(b)  -- 输出: banana
print(c)  -- 输出: cherry
table.unpack 将 fruits 表中的元素解包为独立的变量 a、b 和 c。


local numbers = {10, 20, 30, 40, 50}
local first, second = table.unpack(numbers, 1, 2)

print(first)   -- 输出: 10
print(second)  -- 输出: 20

table.unpack 只解包 numbers 表中的前两个元素。


local empty = {}
local a, b, c = table.unpack(empty)

print(a)  -- 输出: nil
print(b)  -- 输出: nil
print(c)  -- 输出: nil
当解包空表时,所有的变量都会被赋值为 nil

使用场景

动态参数传递: 在函数调用时,可以使用 table.unpack 将表中的内容作为独立参数传入。
简化代码: 当需要从表中获取多个值时,使用 table.unpack 可以使代码更加简洁和易读。

注意事项

table.unpack 函数的参数要求是表。如果传入一个非表的值,会导致错误。
如果解包的范围超出表的长度,Lua 会自动将超出部分视为 nil。

删除 table.remove

table.remove 是 Lua 中用于从表(数组)中删除元素的函数。

这个函数非常实用,尤其是在需要动态地移除表中的某个元素时。


table.remove(table, [position])
table: 需要删除元素的目标数组(表)。
position (可选): 要删除的元素的索引。如果未指定,默认删除表中的最后一个元素。
local fruits = {"apple", "banana", "cherry"}
local removedFruit = table.remove(fruits)

print(removedFruit)  -- 输出: cherry
for _, v in ipairs(fruits) do
    print(v)  -- 输出: apple, banana
end

table.remove 删除了 fruits 表中的最后一个元素,并返回了被删除的值。



local fruits = {"apple", "banana", "cherry"}
local removedFruit = table.remove(fruits, 2)  -- 删除索引为 2 的元素

print(removedFruit)  -- 输出: banana
for _, v in ipairs(fruits) do
    print(v)  -- 输出: apple, cherry
end
table.remove 删除了 fruits 表中索引为 2 的元素 "banana"local numbers = {1, 2, 3, 4, 5}
table.remove(numbers)  -- 删除最后一个元素 5

for _, v in ipairs(numbers) do
    print(v)  -- 输出: 1, 2, 3, 4
end
table.remove 删除表中的最后一个元素

table.remove 是原地操作,它直接改变传入的表,而不是返回一个新的表。

删除元素后,表中的后续元素会自动向前移动,以填补删除的空位,这会影响元素的索引。

如果指定的索引大于表的长度,table.remove 不会执行任何操作,并且返回 nil。

拷贝 table.move

table.move 是 Lua 中用于移动数组元素的函数。

这个函数用于将一个表(数组)中的一段元素复制到另一个位置,可以用于数组元素的重排、复制或移动,非常方便。

table.move(source, start, end, dest, [metatable])
source: 源表(源数组),即要移动元素的表。
start: 源表中要移动开始的索引位置(包括该位置)。
end: 源表中要移动结束的索引位置(包括该位置)。
dest: 目标表中插入元素的起始位置。
metatable (可选): 如果为真,目标表会保持源表的元表不变。

主要特性

table.move 可以用来移动源表中的一段元素,写入到目标表的指定位置。

该函数可以同时支持正向和反向的移动。

可以有效处理重叠的区域或不重叠的区域。

local fruits = {"apple", "banana", "cherry", "date", "fig"}
table.move(fruits, 2, 4, 1)  -- 将索引 2 到 4 的元素移动到索引 1 位置

for _, v in ipairs(fruits) do
    print(v)  -- 输出: banana, cherry, date, date, fig
end

banana、cherry 和 date 被移动到表的前面,原来的元素被覆盖。



local numbers = {1, 2, 3, 4, 5}
table.move(numbers, 1, 3, 2)  -- 将索引 1 到 3 的元素移动到索引 2 位置

for _, v in ipairs(numbers) do
    print(v)  -- 输出: 1, 1, 2, 3, 5
end

123 被移动到 2 的位置,且原有位置的元素将随着移动进行覆盖。



local letters = {"a", "b", "c", "d", "e"}
table.move(letters, 2, 4, 1)  -- 将 `b`、`c` 和 `d` 移动到 `1` 位置

for _, v in ipairs(letters) do
    print(v)  -- 输出: b, c, d, d, e
end
b、c 和 d 被移动到表的开头,原有的开头元素被覆盖。

长度#

t = {11,22,33,44,55,66}
print(t[#t]) -- 输出最后一个元素 66
t[#t] = nil -- 移除最后一个元素
t[#t +1 ] = 999 -- 把 999 添加到序列最后
print(t[#t]) -- 999

#失效

print(#{1, 2, nil, 3}) -- 4
print(#{1, 2, nil, 3, nil}) --2
# ipairs 失效

数组中的 nil 影响求长度,长度不定的数组,无法通过下标对其遍历,迭代函数 ipairs
遍历则会中止。

array = {1,2,3,4,5,6,7,8,9,10}
print("len =",#array)
for k,v in ipairs(array) do
print(k,v)
end
print("====================")
array2 = {1,2,3,4,nil,6,7,8,9,10}
print("len =",#array2)
for k,v in ipairs(array2) do
print(k,v)
end
print("--------------------")
for i=1,#array2 do
print(i,array2[i])
end

len =   10
1       1
2       2
3       3
4       4
5       5
6       6
7       7
8       8
9       9
10      10
====================
len =   10
1       1
2       2
3       3
4       4
--------------------
1       1
2       2
3       3
4       4
5       nil
6       6
7       7
8       8
9       9
10      10
pairs有效
array2 = {11,22,33,44,nil,66,77,88,99,100,nil}
for k,v in pairs(array2) do
print(k,v) --pairs 打印的时候,nil 是不输出的。
end 

1       11
2       22
3       33
4       44
6       66
7       77
8       88
9       99
10      100

在 Lua 中,pairs 和 ipairs 都是用于遍历表(数组和字典)的函数,但它们有一些重要的区别。以下是两者的主要区别:

  1. 遍历方式
    ipairs:

仅用于遍历一维数组(即表中的整数索引元素)。
按照索引从 1 开始,连续遍历,每次迭代返回下一个索引和对应的值。
遇到第一个 nil 值时停止迭代。

local fruits = {"apple", "banana", "cherry", nil, "date"}

for index, value in ipairs(fruits) do
    print(index, value)
end
-- 输出:
-- 1   apple
-- 2   banana
-- 3   cherry

pairs:

用于遍历表中的所有键值对。
可用于所有类型的表,无论是数值索引还是字符串索引。
不保证返回元素的顺序。

local fruits = {["a"] = "apple", ["b"] = "banana", ["c"] = "cherry"}

for key, value in pairs(fruits) do
    print(key, value)
end
-- 输出(顺序可能不固定):
-- a   apple
-- b   banana
-- c   cherry


  1. 应用场景

ipairs:

更适合用于遍历数组,特别是没有 nil 值的连续索引表。
常用于处理有序数据。

pairs:

更适合用于遍历包含混合类型键(如数字和字符串)和不连续键的表(即散列表)。
通常用于字典结构或以键值对形式的数据。

  1. 停止条件

ipairs:

一旦遇到第一个 nil 值,它将停止迭代。因此,如果数组中存在 nil,后续元素将不会被遍历。

pairs:

会遍历表中的所有元素,无论元素是否为 nil。它返回的是整个表的所有键值对,包含任何形式的 nil 值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可能只会写BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值