# Take some pits of table length in lua and how to improve

【Foreword】

Without further ado, let's look at an example:

local tab = {
    
    a = 1, 2,3,4}
local tab1 = {
    
    1,2}
print(#tab,#tab1)-->3	2

#tab=3 in the output of this print, obviously there are 4 elements, and the length is only equal to 3. This is a bug I encountered in my work. Next, I will analyze the source code and provide the improvement method.

[#Analysis of underlying source code]

# stands for the length. For strings, take the length of the string, and for tables it's a bit more complicated.

Tables in lua can use numbers or strings as keys, and the # sign gets the size of the first consecutive part of the index using an integer, if t[1] == nil, even if t[5], t[6 ], t[7] exists, #t is still zero.

It may be easier to understand by looking at the code.

int luaH_getn (Table *t) {
    
    
  unsigned int j = t->sizearray;
  if (j > 0 && ttisnil(&t->array[j - 1])) {
    
    
    /* there is a boundary in the array part: (binary) search for it */
    unsigned int i = 0;
    while (j - i > 1) {
    
    
      unsigned int m = (i+j)/2;
      if (ttisnil(&t->array[m - 1])) j = m;
      else i = m;
    }
    return i;
  }
  /* else must find a boundary in hash part */
  else if (t->node == dummynode)  /* hash part is empty? */
    return j;  /* that is easy... */
  else return unbound_search(t, j);
}

This is the method to find the length of table in lua5.1. In the function, t->array is an array, and an index i is found by the dichotomy method, so that t[i] exists and t[i+1] is nil, and i is used as The length of the table is returned. Therefore, the length of the table taken in lua does not indicate the number of elements. Only when it is certain that the elements in the table are consecutive integers starting from 1 as ke can the correct result be obtained. For example, when creating a list, add an element at the end through t[#t +1] = new_node. Next, we will use pairs to traverse the table to get the length of the table.

[# Take the length of the table and replace it with pairs to traverse the table]

function GetTalbleMapLen(tab)
    local len = 0
    for _, v in pairs(tab) do        
        if v then len = len+1 end        
    end
    return len
end
local tab = {
    
    a = 1, 2,3,4}
print(GetTalbleMapLen(tab))-->4

Guess you like

Origin blog.csdn.net/qq_42541751/article/details/123219957