用非整数键删除表

时间:2018-09-26 11:31:09

标签: lua

我想制作我的removeIf(aTable, unaryPredicate)函数,以删除满足谓词的元素。

我已经凭直觉编写了以下代码,但对我来说却令人惊讶:

for k, v in pairs(aTable) do
    if unaryPredicate(v) then
        atable[k] = nil
    end
end

nextpairs背后的神奇力量是什么使该代码有效。据我所知,它精确地迭代了sizeof(aTable)倍。

2 个答案:

答案 0 :(得分:3)

Lua表本质上实现为哈希表。哈希表存储着(key, value)对数组。

next 使用哈希可以快速跳至其键应在表中的位置。

但是,请注意,nil的实现中有一个next检查:

if (!ttisnil(&t->array[i])) {  /* a non-nil value? */

这是因为将nil分配给表的键时,它会更新哈希表中的(键,值)对,但实际上不会删除该条目。因此,您在哈希表中留下了(键,nil)项。这种设计允许在为现有键分配值时,通过next进行的迭代不受影响,而在分配给nil时,包括

但是,这是实施细节。在表实现公开的API中,哈希表中是否有nil条目是完全不可见的。每个函数从外部将这些nil键当作缺席的方式来对待。

答案 1 :(得分:1)

next仅取决于表中的键。该循环删除值,但不删除键(在Lua的当前实现中)。该文档明确指出,您可以像循环那样从表中删除值。它还说您不能添加带有新键的新条目,完全是因为这会使next感到困惑。