我有一个包含两个值的表,一个是名称(字符串和唯一),另一个是数字值(在本例中为 hearts )。我想要的是:通过 hearts 对表格进行排序,但是当存在平局时(例如 hearts 相等),可以随机搜索这些项目。通过标准排序功能,在连接的情况下,顺序总是相同的,并且每次排序功能工作时我都需要它不同。 这是一个例子:
tbl = {{name = "a", hearts = 5}, {name = "b", hearts = 2}, {name = "c", hearts = 6}, {name = "d", hearts = 2}, {name = "e", hearts = 2}, {name = "f", hearts = 7}}
sort1 = function (a, b) return a.hearts > b.hearts end
sort2 = function (a, b)
if a.hearts ~= b.hearts then return a.hearts > b.hearts
else return a.name > b.name end
end
table.sort(tbl, sort2)
local s = ""
for i = 1, #tbl do
s = s .. tbl[i].name .. "(" .. tbl[i].hearts .. ") "
end
print(s)
现在,使用函数sort2
我认为我遇到了问题。问题是,a.hearts == b.hearts
会发生什么?在我的代码中,它只是通过他们的名字命名关系,而不是我想要的。我有两个想法:
sort1
。rnd
,这是一个随机数。然后在sort2
中a.hearts == b.hearts
按a.rnd > b.rnd
订购商品。sort2
中,a.hearts == b.hearts
生成随机的true或false并返回它。它不起作用,我理解这是因为随机的真/假会使订单功能崩溃,因为可能存在不一致。我不喜欢1(因为我想在排序功能中做所有事情)和2(因为它需要添加一个值),我想做3之类的工作。问题是:有没有办法以简单的方式做到这一点,这样做的最佳方式是什么? (也许,方法1或2是最佳的,我不能得到它。)
奖金问题。此外,我需要修复一个项目并对其他项目进行排序。例如,假设我们希望"c"
成为第一个。制作一个单独的表只包含要排序的项目,对表格进行排序然后添加固定项目是不是很好?
答案 0 :(得分:3)
math.randomseed(os.time())
tbl = {{name = "a", hearts = 5}, {name = "b", hearts = 2}, {name = "c", hearts = 6}, {name = "d", hearts = 2}, {name = "e", hearts = 2}, {name = "f", hearts = 7}}
function rnd_sort(tbl, corrections)
local rnd = corrections or {}
table.sort(tbl,
function (a, b)
rnd[a.name] = rnd[a.name] or math.random()
rnd[b.name] = rnd[b.name] or math.random()
return a.hearts + rnd[a.name] > b.hearts + rnd[b.name]
end)
end
function show(tbl)
local s = ""
for i = 1, #tbl do
s = s .. tbl[i].name .. "(" .. tbl[i].hearts .. ") "
end
print(s)
end
for i = 1, 10 do
rnd_sort(tbl)
show(tbl)
end
rnd_sort(tbl, {c=1000000}) -- now "c" will be the first
show(tbl)
答案 1 :(得分:2)
这是一个用于改组(加扰)数字索引表的快速函数:
ViewPager
答案 2 :(得分:1)
如果你可以自由地引入一个新的依赖项,你可以使用lazylualinq为你完成这项工作(或者查看它如何对序列进行排序,如果你不需要其余的那些):
local from = require("linq")
math.randomseed(os.time())
tbl = {{name = "a", hearts = 5}, {name = "b", hearts = 2}, {name = "c", hearts = 6}, {name = "d", hearts = 2}, {name = "e", hearts = 2}, {name = "f", hearts = 7}}
from(tbl)
:orderBy("x => x.hearts")
:thenBy("x => math.random(-1, 1)")
:foreach(function(_, x) print(x.name, x.hearts) end)