2

我有两张表,一张带有键,另一张带有值。我加入他们以创建一个键值对表。目前我正在使用循环。有没有更好的办法?

local keys={"fruit","bread","drink"}
local vals={"apple","french","milk"}

local kv={}
for i=1,#keys do
  kv[keys[i]]=vals[i]
end
4

2 回答 2

1

面向对象编程?

-- You could do it in one line too, but this looks neater.
local kv = {fruit = "apple", 
            bread = "french",
            drink = "milk"}

print(kv["fruit"])
print(kv.bread) -- Also works
for index, value in pairs(kv) do --Or you could do it in a for loop
    print("index:", index, "value:", value)
end

你会得到:

apple
french
index:  bread   value:  french
index:  fruit   value:  apple
index:  drink   value:  milk
于 2014-08-04T02:39:22.203 回答
0

你没有回复我的评论,但无论如何这里有一个答案。

正如其他人所说,您的代码适用于通用用例。特别是,如果您想kv稍后进行操作,或者以后keys可能values会更改并且kv应该是当前状态的快照。

但是,在某些情况下,有一种更优雅的方式:

如果 的唯一目的kv是稍后迭代它(而不是操纵它或挑选单个值),那么您可以编写一个迭代器,它可以与 一起使用for,就像这样

local keys={"fruit","bread","drink"}
local vals={"apple","french","milk"}:

local function zipkv()
    local i = 0
    return function ()
        i = i + 1
        return keys[i], vals[i]
    end
end


for k,v in zipkv() do
    print("key", k, "value", v)
end

迭代器返回的函数kv将在每次迭代开始时调用,直到第一个返回值为nil. 这样做的好处是您不需要创建第三个表。您可能会争辩说,您正在创建闭包而不是表,但是如果您要kv使用迭代表pairs,那么pairs也只是创建闭包的迭代器。

另一个区别(这是优点还是缺点再次取决于用例)是zipkv总是会遍历keysand的当前状态vals。因此,如果您要在创建迭代器之后更改它们,但在循环使用迭代器之前,您总是会将两个表的当前状态压缩在一起。

所以这是我能想到的一种情况,有一种更优雅(更有效)的解决方案来解决您的问题。但它的适用性有些限制,所以如果你正在寻找“最好的”通用方法,并且你已经找到了,我会说。

于 2013-05-05T22:48:20.120 回答