从Lua表中随机选择一个键。
2014-3-11 9:20:45
收藏:0
阅读:118
评论:4
我想使用Lua中可能的项目列表随机填充网格,其定义如下:
-- 项目
items = {}
items.glass = {}
items.glass.color = colors.blue
items.brick = {}
items.brick.color = colors.red
items.grass = {}
items.grass.color = colors.green
因此,表的键为“glass”,“brick”和“grass”。
如果它们不能通过数值索引进行寻址,如何随机选择其中之一的键?
点赞
用户869951
虽然你的第二种方法语法简洁,但我认为第一种更容易维护。虽然我无法在这里进行测试,但我认为你可以兼得两者的优点,这样行得通:
local items = {
glass = {
color = colors.blue,
},
brick = {
color = colors.red,
},
grass = {
color = colors.green,
},
}
local item_index = {"grass", "brick", "glass"}
local index = math.random(1,3)
board[i][j] = items[item_index[index]]
print('color:', board[i][j].color)
2014-03-11 14:03:12
用户988143
如果你的表不太大,你可以在任意位置断开。这种方法假定你知道表中的条目数量(它不等于#table的值,如果表具有非数字键)。
因此,首先找到表的长度,然后在random(1, length(table))处断开,就像这样:
local items = {} ....
items.grass.color = colors.green
local numitems = 0 -- 找出表的大小
for k,v in pairs(items) do
numitems = numitems + 1
end
local randval = math.random(1, numitems) -- 获取随机点
local randentry
local count = 0
for k,v in pairs(items) do
count = count + 1
if(count == randentry) then
randentry = {key = k, val = v}
break
end
end
好处:您不需要跟踪键。它可以是任何表,您不需要维护它。 坏处和问题:它是O(n)——两个线性通道,因此,如果您有一个大表,这绝不是理想的选择。
2014-03-11 15:18:49
用户2662300
上面的回答假设你知道所有键的内容,这是我今天早些时候无法做到的。我的解决方案:
function table.randFrom( t )
local choice = "F"
local n = 0
for i, o in pairs(t) do
n = n + 1
if math.random() < (1/n) then
choice = o
end
end
return choice
end
解释:我们不能使用 table.getn(t)来获取表的大小,因此我们在使用过程中进行了跟踪。第一项将有1/1 = 1的选择机会。 第二项将有1/2 = 0.5的选择机会,以此类推……
如果扩展到N个项目,第N个项目将有1/N的被选择机会。第一项将有1-(1/2)-(1/3)-(1/4)-……-(1/N)的不被替换机会(记住,它总是最初被选择的)。该系列收敛于1-(N-1)/N = 1/N,等于选择最后一项的机会。
因此,数组中的每个项目具有相等的随机选择机会;它是均匀随机的。这也以O(n)的时间运行,这不是很好,但如果您不知道索引名称,这是您所能做的最好的事情。
2015-01-18 01:43:27
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
嗯,我找到了一个解决方法,但我也愿意听听更好的建议。
第一个解决方案是建立一个辅助表作为第一个表的索引:
item_index = {"grass", "brick", "glass"}然后我可以随机存储这个表的键(
board是一个存储item_index中随机条目的值的矩阵):local index = math.random(1,3) board[i][j] = item_index[index]接下来,我可以按以下方式获取原始列表的详细信息:
我决定采用的第二个解决方案是将定义的元素作为数组元素添加到原始表中:
-- Items items = {} items.glass = {} items.glass.color = colors.blue table.insert(items, items.glass) --- 将项作为数组项添加 items.brick = {} items.brick.color = colors.red table.insert(items, items.brick) --- 将项作为数组项添加 items.grass = {} items.grass.color = colors.green table.insert(items, items.grass) --- 将项作为数组项添加然后,我可以直接使用索引直接访问这些元素:
local index = math.random(1,3) board[i][j] = items[index]它们可以直接检索,无需进行额外的查找: