如何在Lua中获取表的第n个键

时间:2013-02-01 16:07:11

标签: lua

我在Lua中有两个函数,它们创建一个字典表并允许检查一个单词是否存在:

local dictTable = {}
local dictTableSize = 0

function buildDictionary()
    local path = system.pathForFile("wordlist.txt")
    local file = io.open( path, "r")
    if file then
        for line in file:lines() do
            dictTable[line] = true
            dictTableSize = dictTableSize + 1
        end      
        io.close(file)
    end
end

function checkWord(word)
    if dictTable[word] then
        return(true)
    else
        return(false)
    end
end

现在我希望能够生成几个随机单词。但由于单词是键,我如何选择一些,给定dictTableSize。

由于

3 个答案:

答案 0 :(得分:1)

可能有两种方法:你可以用文字保存数组,当你需要选择一个随机词时只需要words[math.random(#words)](只要确保第二个与第一个不同) )。

另一种方法是使用next您需要的次数:

function findNth(t, n)
  local val = next(t)
  for i = 2, n do val = next(t, val) end
  return val
end

这将为b返回findNth({a = true, b = true, c = true}, 3)(订单未定义)。

您可以通过memoizing结果避免重复扫描(此时您最好使用第一种方式)。

答案 1 :(得分:1)

在加载字典时,只需将每个单词的数字索引添加到字典中:

function buildDictionary()
    local path = system.pathForFile("wordlist.txt")
    local file = io.open( path, "r")
    if file then
        local index = 1
        for line in file:lines() do
            dictTable[line] = true
            dictTable[index] = line
            index = index + 1
        end      
        io.close(file)
    end
end

现在你可以得到一个像这样的随机词:

function randomWord()
    return dictTable[math.random(1,#dictTable)]
end

旁注:nil在Lua条件中的计算结果为false,因此可以这样写checkWord

function checkWord(word)
    return dictTable[word]
end

另一方面,如果将字典功能包装到对象中,您将获得更少的全局命名空间的压缩:

local dictionary = { words = {} }

function dictionary:load()
    local path = system.pathForFile('wordlist.txt')
    local file = io.open( path, 'r')
    if file then
        local index = 1
        for line in file:lines() do
            self.words[line] = true
            self.words[index] = line
            index = index + 1
        end      
        io.close(file)
    end
end

function dictionary:checkWord(word)
    return self.words[word]
end

function dictionary:randomWord()
    return self.words[math.random(1,#self.words)]
end

然后你可以说:

dictionary:load()
dictionary:checkWord('foobar')
dictionary:randomWord()

答案 2 :(得分:0)

这是您按照自己的方式使用单词表的权衡。加载后我会反转单词表,这样你就可以按索引引用单词。像这样的东西:

-- mimic your dictionary structure
local t = {
    ["asdf"] = true, ["wer"] = true, ["iweir"] = true, ["erer"] = true
}

-- function to invert your word table
function invert(tbl)
    local t = {}
    for k,_ in pairs(tbl) do
        table.insert(t, k)
    end
    return t
end

-- now the code to grab random words
local idx1, idx2 = math.random(dictTableSize), math.random(dictTableSize)
local new_t = invert(t)
local word1, word2 = new_t[idx1], new_t[idx2]
-- word1 and word2 now have random words from your 'dictTable'
相关问题