我有一个带有两个值的表,一个是名称(字符串和唯一),另一个是数字值(在这种情况下为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.heartsa.rnd > b.rnd排序项目时。
sort2中,当a.hearts == b.hearts随机生成true或false并将其返回时。它不起作用,我知道发生这种情况是因为随机的true / false会使订单函数崩溃,因为可能存在不一致的情况。


我不喜欢1(因为我想在排序函数中做所有事情)和2(因为它需要添加一个值),所以我想做类似3但可以工作的事情。问题是:有没有一种简单的方法可以做到这一点,什么是最优的方法? (也许方法1或2是最佳方法,但我不明白)。

奖金问题。此外,我需要修复一个项目并对其他项目进行排序。例如,假设我们希望"c"首先。制作一个仅包含要排序项目的单独表格,对表格进行排序,然后添加固定项目是否很好?

最佳答案

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)

07-25 23:01
查看更多