按值

时间:2015-08-11 06:53:50

标签: sorting lua lua-table computercraft

假设我有一张这样的桌子:

{
   value = 4
},
{
   value = 3
},
{
   value = 1
},
{
   value = 2
}

我希望迭代它并按顺序打印值,因此输出如下:

1
2
3
4

如何执行此操作,我了解如何使用ipairspairs以及table.sort,但只有在使用table.insert并且密钥有效时才能使用,我需要按照值的顺序循环遍历。

我尝试了自定义功能,但它只是以错误的顺序打印出来。

我试过了:

  • 创建索引并循环
  • 对表进行排序(抛出错误:尝试在表和表上执行__lt)
  • 并且各种各样的,索引和其他表格的组合不仅不起作用,而且使它变得非常复杂。

我很好,真的很难过。

2 个答案:

答案 0 :(得分:2)

  

对表格进行排序

这是正确的解决方案。

  

(抛出错误:尝试在表和表上执行__lt)

听起来你试图使用split(504, 18)

为了让Lua能够对值进行排序,它必须知道如何比较它们。它知道如何比较数字和字符串,但默认情况下它知道如何比较两个表。考虑一下:

a < b

如果我打电话给local people = { { name = 'fred', age = 43 }, { name = 'ted', age = 31 }, { name = 'ned', age = 12 }, } 人,Lua怎么知道我的意图?我不知道'年龄'或'名字'是什么意思,或者我想用它来比较。我必须告诉它。

可以在表格中添加 metatable ,告诉Lua sort运算符对表的含义,但您也可以为<提供回调函数告诉它如何比较两个对象。

您向sort提供一个接收两个值的函数,并使用您对表的了解返回第一个是否小于第二个值。就你的表而言:

sort

答案 1 :(得分:0)

如果您想保持原始表不变,可以创建一个自定义的“按值排序”迭代器,如下所示:

local function valueSort(a,b)
    return a.value < b.value;
end

function sortByValue( tbl ) -- use as iterator
    -- build new table to sort
    local sorted = {};
    for i,v in ipairs( tbl ) do sorted[i] = v end;
    -- sort new table
    table.sort( sorted, valueSort );
    -- return iterator
    return ipairs( sorted );
end

调用sortByValue()时,它会将tbl克隆到新的sorted表,然后对已排序的表进行排序。然后它将sorted表交给ipairs()ipairs输出要由for循环使用的迭代器。

使用:

for i,v in sortByValue( myTable ) do
  print(v)
end

虽然这可以确保您的原始表保持不变,但它的缺点是,每次进行迭代时,迭代器必须克隆myTable以创建新的sorted表,然后{{1}那个table.sort表。

如果性能至关重要,您可以通过“缓存”sorted迭代器完成的工作来大大加快速度。更新的代码:

sortByValue()

每次向/ local resort, sorted = true; local function valueSort(a,b) return a.value < b.value; end function sortByValue( tbl ) -- use as iterator if not sorted then -- rebuild sorted table sorted = {}; for i,v in ipairs( tbl ) do sorted[i] = v end; resort = true; end if resort then -- sort the 'sorted' table table.sort( sorted, valueSort ); resort = false; end -- return iterator return ipairs( sorted ); end 设置myTable添加或删除元素。这让迭代器知道它需要重建sorted = nil表(并重新排序)。

每次更新其中一个嵌套表中的sorted属性时,请设置value。这让迭代器知道它必须做resort = true

现在,当您使用迭代器时,它将尝试重新使用缓存的table.sort表中以前的排序结果。

如果找不到sorted表(例如,首次使用迭代器,或者因为设置sorted强制重建),它将重建它。如果它看到它需要求助(例如,在第一次使用时,或者如果sorted = nil表被重建,或者如果你设置sorted)那么它将采用resort = true表。