Lua中ipair和pair关键字的区别是什么?

1.7k 词

ipair是从key=1,开始累加,遇到val是nil就结束循环。
pair输出的结果和table定义的顺序是一致的(非数组不保证与声明的顺序一致)。

pairs()可以遍历整个table,即包括数组及非数组部分。
ipairs()函数用于遍历table中的数组部分。

i= integer ,integer key

1:使用ipair循环

local tt =  
{  
    [1] = "test3",  
    [4] = "test4",  
    [5] = "test5"  
}  

for i,v in ipairs(tt) do    
    print( tt[i] )  
end 

运行结果:

test3

2:使用pair循环

local tt =  
{  
    [1] = "test3",  
    [4] = "test4",  
    [5] = "test5"  
}  

for i,v in pairs(tt) do    
    print( tt[i] )  
end 

运行结果:

test3
test4
test5

怎么解决,数组里,某个元素是nil后面就不遍历的问题:

@ms2008老师的方案如下:


local t = {10, nil, 30}
for k,v in ipairs(t) do
    print("in", k,v)
end
print("=============")
for i=1, select('#', unpack(t)) do
    local param = select(i, unpack(t))    
    print(param)
end

在讨论ipair和pair的过程中,触发了另外一个问题,就是对lua的map型table按照Map的value,而不是key进行排序,对key的排序lua有sort方法提供支持,而对value的排序是没有的,下面提供了一个对value进行排序的演示算法,是用MoonScript实现的排序算法,应用在反描模块中,对指定用户port访问量的大小进行排序:

class GUtils 
  @mapsort: (board) =>
    b_len = 0 
    for k,v in pairs(board)
      b_len = b_len + 1 

    a1 = {}
    a2 = {}

    i = 0 
    for k,v in pairs(board)
      i = i + 1 
      a1[i] = k 
      a2[i] = v 

    for i = 1, b_len
       max = a2[i]
       for j = i + 1, b_len 
         if a2[j] > max 
           tmp = a2[j]
           a2[j] = max 
           a2[i] = tmp 
           max = tmp 
           tmp1 = a1[j]
           a1[j]  = a1[i]
           a1[i] = tmp1

    ret = {}
    for k,v in ipairs(a1) 
      ret[k] = {a1[k], a2[k]}
    return ret 

下面是纯lua实现,而不是用moonc编译的上面的.moon文件:

local board = { 
  ['0.0.0.1'] = 1,
  ['0.0.0.5'] = 5,
  ['0.0.0.3'] = 3,
  ['0.0.0.2'] = 2,
  ['0.0.0.9'] = 9,
  ['0.0.0.3'] = 3,
  ['0.0.0.6'] = 6 
}
local mapsort
mapsort = function(board)
  local b_len = 0 
  for k, v in pairs(board) do
    b_len = b_len + 1 
  end 
  local a1 = { } 
  local a2 = { } 
  local i = 0 
  for k, v in pairs(board) do
    i = i + 1 
    a1[i] = k 
    a2[i] = v 
  end 

  for i = 1, b_len do
    local max = a2[i]
    for j = i + 1, b_len do
      if a2[j] > max then
        local tmp = a2[j]
        a2[j] = max 
        a2[i] = tmp
        max = tmp
        local tmp1 = a1[j]
        a1[j] = a1[i]
        a1[i] = tmp1
      end
    end
  end
  local ret = { }
  for k, v in ipairs(a1) do
    ret[k] = {
      a1[k],
      a2[k]
    }
  end
  return ret
end

print("########")
local ret = mapsort(board)
for k, v in ipairs(ret) do
  print(ret[k][1], ret[k][2])
end