我想制作我的removeIf(aTable, unaryPredicate)
函数,以删除满足谓词的元素。
我已经凭直觉编写了以下代码,但对我来说却令人惊讶:
for k, v in pairs(aTable) do
if unaryPredicate(v) then
atable[k] = nil
end
end
next
或pairs
背后的神奇力量是什么使该代码有效。据我所知,它精确地迭代了sizeof(aTable)倍。
答案 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
感到困惑。