SoFunction
Updated on 2025-04-08

Summary of the difference between pairs and ipairs in Lua

Preface

Used recentlynginx_lua_module The module writes a traffic forwarding thing, and forwards it to another place according to the traffic ratio according to the Header, Body, and Cookies. After reading the code written by my predecessors, some use pairs when looping in it, and some use ipairs, which is very puzzled. Fortunately, there is an electronic version of Lua's official websiteProgramming in Lua 》, it is very convenient to learn. The following content is my notes and thoughts about Lua when I was a beginner. If it is incorrect, please feel free to correct it.

The standard library provides centralized iterators, including iterating the () of each line of the file, iterating the (pairs) of the table element, iterating the (ipairs) of the array element, iterating the () of the words in the string, etc.

The difference between pairs and ipairs

A general iterator maintains a state (the current iteration location) internally, but Lua's iterator is Stateless (stateless), the advantage of this is that it can be repeated multiple iterations. Unlike Python's Iterator and Iterable, if you iterate multiple times, you need to get an iterator from Iterable. Lua's iterator needs to be maintained by itself when looping.

Every iteration, for will call the iterator function, and there are 2 parameters passed in, one is a stateless object to be iterated, and the other is a control parameter (the state of iteration, 1 2 3…).

For example, the following cycle:

a = {"one", "two", "three"}
for i, v in ipairs(a) do
 print(i, v)
end

First, ipairs(a) is executed and returns three values: the iter function (from here, Lua has a "first-class function" like Python), the iterated object a, and the subscript 0 of the iterative start. Then, the for loop calls iter(a, 0) for the first time (the parameter is as we said above), obtaining the value v of the current subscripts i and a[i] of the return value, and assigning these two values ​​to the variables i and v when the for loop is defined. Use Lua to implement this logic, as follows:

function iter (a, i)
 i = i + 1
 local v = a[i]
 if v then
  return i, v
 end
end
 
function ipairs (a)
 return iter, a, 0
end

Then the logic of the for loop call above is similar to the following. First, call the ipairs function to get the iter function, and then call the iter function each time.

iter_function, stateless, index = ipairs(a)
iter_function(stateless, index)
1  one
iter_function(stateless, index+1)
2  two
iter_function(stateless, index+2)
3  three

Another point to note is that the above Lua code judges v and will continue if it is not nil. This is also true in the actual for loop. For example, in our following loop, because the second value is nil, the first element will appear when printing.

a = {"one", nil, "three"}
for i, k in ipairs(a) do
 print(i, k)
end
1  one

Then we are talking about pairs. In fact, from the above description, it can also be found that ipars starts from 1 to nil, so it will be inconvenient if there is nil in the table but you want to take out all the elements. You can use pairs at this time.

function pairs (t)
 return next, t, nil
end

The logic of for loop has been mentioned above. The difference between pairs here is that the three elements it returns are next function, the iterated object a, and the state of starting nil. You can see that there are two main differences: the first is the function next . The difference between iter is that it returns the next key value and the order is fixed until no key value is correct and the iteration ends.

We can see their differences through several examples.

a = {"one", "two", "three"}
for i, v in ipairs(a) do
 print(i, v)
end
for i, v in pairs(a) do
 print(i, v)
end

The print value is as follows:

1       one
2       two
3       three
1       one
2       two
3       three

The two results are the same, because in this table, the keys are both 1 2 3, so the pair loops with iter (the subscript starts from 1 to the first value that is not nil), or the ipairs loops with next (the subscript starts from nil to traverse all key values), and the effects are the same.

t = {
 a = "apple",
 b = "baby",
 c = "cool"
}
for i, v in ipairs(t) do
 print(i, v)
end
for k, v in pairs(t) do
 print(k, v)
end

The result is that pairs can print out the results, and the result printed by ipairs is empty. Because the value of t[1] is nil , the ipairs loop stops at the beginning.

Let’s take a look at the last set of examples (copied from Reference 1):

ocal t = {
 a=100,10,20,[5]=30
}
 
for key,value in ipairs(t) do
 print(key,value) 
 --1 10
 --2 20
end
 
for key,value in pairs(t) do
 print(key,value) 
 --1 10
 --2 20
 --a 100
 --5 30
end

The results are shown in the comments, so there is no need to explain them.

After understanding their differences, it is very easy to use. ipairs are generally used for tables that require subscripts and iterate over array forms; pairs can be used to iterate over dictionary tables.

Summarize

The above is the entire content of this article. I hope that the content of this article has a certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.

References:

  • Table User Manual
  • 《 Programming in lua 》