b而a&b是数组或表格

我是一个新的程序员,并从lua开始。 我想做一个数组-b的函数,下面是我的程序,它不能很好地工作

function delTwo (a ,b)  
local i = 0 
   local lengthA = #a
   local lengthB = #b


  for i = 1 ,lengthA do
   for j =1 , lengthB do
   if a[i]==b[j] then
   a[i] = nil
   end
  end

  for i = 1 , lengthA do
   if a[i]~= nil then
   retrun a[i]
   end
  end
  end

  end

a = {10, 20, 30} 
b={11,20,122}
for element in delTwo (a ,b)  do 
  print(element) 
end

我有两个问题,第一个是输入:16:'='期望'a'retrun a [i]我应该改变为retrun = a [i],它们之间的区别是什么?

第二个是输入:3:尝试获取局部'a'的长度(一个零值)这是什么问题,即使我改变为本地lengthA = table.getn(a)会有输入:3:错误的参数#1到'getn'(表预计,没有)


第一个问题已经回答了,但对于第二个,那只是意味着a在你的程序执行的一些点是nil (== null )。 尽管如此,我还是无法用你的例子重复一遍。

我不完全确定你想要实现什么,但我建议你首先创建一个函数,该函数创建一个存储所需结果的新表,然后使用pairs (或正常循环)对其进行迭代。 如下所示:

function delTwo(a, b)
    local result = {}
    --# Logic here.
    --# Use result[#result + 1] = ... to insert values.
    return result
end

for k, v in pairs(delTwo(a,b)) do print(k, v) end

首先,你的缩进掩饰一个问题,你之间平衡for S和end秒。

你有什么是:

function delTwo (a ,b)  
  local i = 0 
  local lengthA = #a
  local lengthB = #b

  for i = 1, lengthA do

    for j = 1, lengthB do
      if a[i] == b[j] then
        a[i] = nil
      end
    end

    for i = 1, lengthA do --// Iterating i while iterating i. Bad things happen!
      if a[i] ~= nil then
        return a[i]
      end
    end

  end

end

此外,因为你正在修改a循环内,它的长度变小,你会拥有一个无效的索引访问它。


然后就是你如何使用delTwo的返回值。

以下是关于迭代器如何在Lua中工作的解释:http://lua-users.org/wiki/IteratorsTutorial

当你for i in <expr>写入类似于for i in <expr><expr>必须返回三个值:一个迭代器函数,一个状态对象和一个初始值。

每次迭代时,将使用状态对象和当前值(从<expr>的初始值开始)调用迭代器函数。 如果它返回nil ,则迭代停止,否则其返回值分配给您的循环变量,执行for循环的主体,并且迭代器函数将再次用相同的状态对象和新的当前值调用,即第一个循环变量(在这种情况下, i )。

一个(相对)简单的例子可以帮助你理解:

local state = {}
state["toggle"] = true

function iterator_func(state, prev_i)
    --// Calculate current value based on previous value
    i = prev_i + 1

    --// Stop iteration if we've had enough
    if i > 10 then
        return nil
    end

    local msg
    if state["toggle"] then
        msg = "It's on!"
        state["toggle"] = false
    else
        msg = "It's off!"
        state["toggle"] = true
    end

    return i, i*2, i*3, msg
end

--// Notice the initial value is 0, the value *before* our first iteration
for  i, double, triple, msg  in  iterator_func, state, 0  do
    print(tostring(i)..", "
          ..tostring(double)..", "
          ..tostring(triple)..", "
          ..tostring(msg))
end

--// Prints:
--//   1, 2, 3, It's on!
--//   2, 4, 6, It's off!
--//   ...
--//   10, 20, 30, It's off!

Lua带有两个迭代器生成器函数: ipairspairs 。 他们都拿一张表并返回for循环所需的值,以迭代该表中存储的值。

ipairs需要一个数字键从1到#table的表,并生成一个迭代器,它将按顺序遍历这些索引,每次返回索引和值时:

for i, v in ipairs( { 10, 20, 30 } ) do
    print("["..i.."] = " .. v)
end
--// Prints:
--//    [1] = 10
--//    [2] = 20
--//    [3] = 30

pairs任何类型的表并生成一个迭代器,该对迭代器返回键和值对,其中对以任意顺序进行。 在这种情况下,键可以是除nil之外的任何东西,甚至表格!

aKey = {}
t = { ["First"] = 10, [2.0] = 20, [aKey] = 30 }

for k, v in pairs(t) do
    print("["..tostring(k).."] = " .. tostring(v))
end
--// Prints something like:
--//    [table: 0x95860b0] = 30
--//    [First] = 10
--//    [2] = 20

所以,你在这里有两种方法。

如果你想让delTwo返回一个表,你必须这样写for循环:

for idx, element in ipairs(delTwo(a, b)) do
   print(element)
end    
--// delTwo *must* return a table with correct numeric indices

或者像这样:

for _, element in pairs(delTwo(a, b)) do
   print(element)
end
--// Conventionally, you use _ as a variable name if you plan to just ignore it.

这是你要学习的东西。 这是一段很大的代码,但我希望你能理解它并从中学习一些东西。

--//////////////////////////////////////////////////////////////////////////
--//
--// APPROACH #1
--//

--//
--// This function modifies table a in place,
--// removing elements that are also found in b
--//
local function delTwo_1(a, b)
    local lengthB = #b

    --// a's length may change if we remove an element from it,
    --// so iterate over b and recalculate a's length every iteration.
    for j = 1, lengthB do
        local lengthA = #a
        for i = 1, lengthA do       
            if a[i] == b[j] then
                table.remove(a, i)

                --// Don't use  " a[i] = nil ".
                --// This will just leave you with a nil element in the "middle"
                --// of the table, and as it happens ipairs() stops
                --// at the first nil index it finds.

                --// So:
                --//   a = { [1] = 10, [2] = 20, [3] = 30}
                --//   a[2] = nil
                --//   -- a is now { [1] = 10, [2] = nil, [3] = 30 }.
                --//
                --//   -- ipairs(a) will now return (1, 10) and then stop.
                --//
                --//   -- pairs(a) will return both (1, 10) and (3, 30)
            end
        end
    end

    --// Return table a if you want,but it's been modified "outside" as well
    return a
end

--//////////////////////////////////////////////////////////////////////////
--//
--// APPROACH #2
--//

--//
--// This function calculates the difference between two tables,
--// without modifying any of them.
--// It will be used in our iterator generator.
--//
local function tableDiff(a, b)
    local res = {}

    for i = 1, #a do
        local skip = false

        for j = 1, #b do
            if a[i] == b[j] then
                skip = true
                break
            end
        end

        if not skip then
            res[#res+1] = a[i]
        end
    end

    return res
end

--//
--// This function is an iterator generator.
--// It returns an iterator function, a state object and an initial value
--//
local function delTwo_2(a, b)   

    --// Some preliminary calculations...
    local res = tableDiff(a, b)

    --// We don't really need state in this case, because we could
    --// refer directly to our res variable inside our iterator function,
    --// but this is just for demonstration purposes.
    local state = {}
    state["result"] = res

    local function iterator(state, key)
        local result = state["result"]

        --// Our key is a numeric index, incremented every iteration
        --// before anything else (that's just how it works)
        key = key + 1

        if key > #result then
            --// If key is greater than our table length,
            --//    then we already iterated over all elements.
            --// Return nil to terminate.
            return nil
        end

        local element = result[key]

        --// Just because we can...
        local msg = "We're at element "..key

        return key, element, msg
    end


    local initialKey = 0 --// We start "before" index 1

    return iterator, state, initialKey
end




do
    --// TESTS

    do
        --// TESTING APPROACH #1

        a = {10, 20, 30} 
        b = {11, 20, 122}

        print "*******************  delTwo_1  *******************"
        print "Here's delTwo_1's result:"

        --// Table a is modified in place
        delTwo_1(a, b)
        for i, element in ipairs(a) do
          print("["..i.."] = "..tostring(element))
        end

        print()
        print "Here's a after delTwo_1:"
        for i, element in ipairs(a) do
          print("["..i.."] = "..tostring(element))
        end
    end

    print()
    print()

    do
        --// TESTING APPROACH #2
        a = {10, 20, 30} 
        b = {11, 20, 122}

        print "*******************  delTwo_2  *******************"
        print "Here's delTwo_2's result:"
        --// Notice how this compares to what
        --// is returned by our iterator function
        for idx, element, msg in delTwo_2(a, b) do
          print(tostring(element) .. "     (Msg: "..msg..")")
        end

        print()
        print "Here's a after delTwo_2:"
        for i, element in ipairs(a) do
          print("["..i.."] = "..tostring(element))
        end
    end
end

这篇文章是对我有多少空闲时间的证明:)


使用metatables的替代版本

local mt = {    --// Just creates a metatable base
__sub = function (a, b) --// Function is the same as Zecc just formatted differently
    local lengthB = #b
    for j = 1, lengthB do
        local lengthA = #a
        for i = 1, lengthA do
            if a[i] == b[j] then table.remove(a, i) end
        end
    end
    return a
end
}

a = {10, 20, 30}    --// Same arrays
b = {11, 20, 122}

setmetatable(a, mt) -- //Use this to give the arrays the __sub function
setmetatable(b, mt)

c = a - b   --// Then you can use the maths operator on it

for k, v in ipairs(c) do --// printing them out gives the same as above
    print(k, v)
end

然后,如果你想以相同的方式使用不同的数组,只需使用setmetatable(x, mt) ,其中x是你想要的函数,它应该工作。

链接地址: http://www.djcxy.com/p/92437.html

上一篇: b while a & b are arrays or tables

下一篇: Merge function in Lua