调用table.sort返回nil

我正在尝试对包含两个名为'pt'和'angle'的键的表中的表'array'进行排序。我想根据它们的'angle'值对'array'元素进行排序。据我理解,table.sort的代码段应该做到这一点:

local array = {}

-- 一些调用
-- table.insert(array, {pt = somePt, angle = someAngle})
-- 多次

local sorted_table = table.sort(array, function(a,b) return a.angle < b.angle end)

但是,sorted_table始终为nil。我在这里做错了吗?

点赞
用户3735873
用户3735873

table.sort 会原地排序表的数组部分。它不会返回一个新的数组。如果你需要保留原来的表,你必须首先复制到一个临时数组。

因此,可以尝试像这样操作:

table.sort(array,function(a,b) return a.angle < b.angle end)
2019-07-16 19:50:19
用户4984564
用户4984564

table.sort 将原表原地排序;也就是说,它改变你给它的表而不返回一个新的表。

如果你想要一个排序后的副本,你需要先自行复制表,然后对其进行排序。

示例代码如下:

local function sorted_copy(tab, func)
  local tab = {table.unpack(tab)}
  table.sort(tab, func)
  return tab
end

这会创建原表的一个副本(至少是数字索引部分,直到某个随机边界处)并对其排序。

2019-07-16 19:52:48
用户7504558
用户7504558

这个排序没有秘密,使用了已经很多次的算法:

function quicksort(t, sortname, start, endi)
  start, endi = start or 1, endi or #t
  sortname = sortname or 1
  if(endi - start < 1) then return t end
  local pivot = start
  for i = start + 1, endi do
    if  t[i][sortname] <= t[pivot][sortname] then
      local temp = t[pivot + 1]
      t[pivot + 1] = t[pivot]
      if(i == pivot + 1) then
        t[pivot] = temp
      else
        t[pivot] = t[i]
        t[i] = temp
      end
      pivot = pivot + 1
    end
  end
  t = quicksort(t, sortname, start, pivot - 1)
  return quicksort(t, sortname, pivot + 1, endi)
end

local array = {}

table.insert(array, {pt = 1, angle = 2})
table.insert(array, {pt = 4, angle = 9})
table.insert(array, {pt = 1, angle = 5})
table.insert(array, {pt = 2, angle = 7})
table.insert(array, {pt = 2, angle = 1})
table.insert(array, {pt = 5, angle = 2})

local s_t = quicksort(array, "angle")

for k,v in pairs(s_t) do
        print(k, "v=", v.pt, v.angle)
end

输出:

1   v=  2   1
2   v=  5   2
3   v=  1   2
4   v=  1   5
5   v=  2   7
6   v=  4   9
2019-07-17 15:47:15