Skip to content

迭代器

迭代器是 Lua 中用于遍历集合(如表)的工具。本章节将介绍 Lua 中迭代器的概念、类型和使用方法。

什么是迭代器

迭代器是一种可以遍历集合中所有元素的机制。在 Lua 中,迭代器通常是一个函数,它每次调用都会返回集合中的下一个元素,直到所有元素都被遍历完毕。

迭代器的类型

无状态迭代器

无状态迭代器不保留任何状态,每次调用都是独立的。最常见的无状态迭代器是 ipairspairs

ipairs

ipairs 用于遍历表中的数组部分,从索引 1 开始,按顺序遍历到第一个 nil 值:

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
for i, fruit in ipairs(fruits) do
  print(i, fruit)
end

输出:

1	苹果
2	香蕉
3	橙子
4	葡萄

pairs

pairs 用于遍历表中的所有键值对,包括数组部分和非数组部分:

lua
local person = {
  name = "张三",
  age = 30,
  gender = "男"
}
for key, value in pairs(person) do
  print(key, value)
end

输出:

name	张三
age	30
gender	男

有状态迭代器

有状态迭代器会保留遍历的状态,通常使用闭包来实现。

lua
function values(t)
  local i = 0
  return function()
    i = i + 1
    return t[i]
  end
end

local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
for fruit in values(fruits) do
  print(fruit)
end

输出:

苹果
香蕉
橙子
葡萄

自定义迭代器

示例 1:遍历数字范围

lua
function range(from, to, step)
  step = step or 1
  local i = from - step
  return function()
    i = i + step
    if i <= to then
      return i
    end
  end
end

for i in range(1, 10, 2) do
  print(i)
end

输出:

1
3
5
7
9

示例 2:遍历字符串中的单词

lua
function words(str)
  local pos = 1
  return function()
    local start, end_pos = str:find("%a+", pos)
    if start then
      pos = end_pos + 1
      return str:sub(start, end_pos)
    end
  end
end

local str = "Hello World Lua"
for word in words(str) do
  print(word)
end

输出:

Hello
World
Lua

泛型 for 循环

泛型 for 循环的语法如下:

lua
for <变量列表> in <表达式> do
  <循环体>
end

泛型 for 循环会执行以下步骤:

  1. 计算 in 后面的表达式,得到一个迭代器函数、一个状态变量和一个控制变量
  2. 调用迭代器函数,传入状态变量和控制变量
  3. 如果迭代器函数返回 nil,则循环结束
  4. 否则,将返回值赋给变量列表,并执行循环体
  5. 重复步骤 2-4

示例:使用泛型 for 循环遍历表

lua
local fruits = {"苹果", "香蕉", "橙子", "葡萄"}
for i, fruit in ipairs(fruits) do
  print(i, fruit)
end

迭代器的应用

示例 1:过滤表中的元素

lua
function filter(t, predicate)
  local i = 0
  return function()
    i = i + 1
    while i <= #t do
      if predicate(t[i]) then
        return t[i]
      end
      i = i + 1
    end
  end
end

local numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for num in filter(numbers, function(x) return x % 2 == 0 end) do
  print(num)
end

输出:

2
4
6
8
10

示例 2:映射表中的元素

lua
function map(t, transform)
  local i = 0
  return function()
    i = i + 1
    if i <= #t then
      return transform(t[i])
    end
  end
end

local numbers = {1, 2, 3, 4, 5}
for num in map(numbers, function(x) return x * 2 end) do
  print(num)
end

输出:

2
4
6
8
10

示例 3:链式迭代器

lua
function chain(...) 
  local tables = {...}
  local currentTable = 1
  local currentIndex = 0
  return function()
    while currentTable <= #tables do
      currentIndex = currentIndex + 1
      if currentIndex <= #tables[currentTable] then
        return tables[currentTable][currentIndex]
      end
      currentTable = currentTable + 1
      currentIndex = 0
    end
  end
end

local arr1 = {1, 2, 3}
local arr2 = {4, 5, 6}
local arr3 = {7, 8, 9}
for num in chain(arr1, arr2, arr3) do
  print(num)
end

输出:

1
2
3
4
5
6
7
8
9

小结

本章节介绍了 Lua 中迭代器的概念、类型和使用方法,包括无状态迭代器(如 ipairspairs)、有状态迭代器、自定义迭代器和泛型 for 循环等内容。掌握这些内容,对于编写 Lua 程序非常重要。