Удалить таблицу нецелыми ключами - PullRequest
0 голосов
/ 26 сентября 2018

Я хотел сделать мою removeIf(aTable, unaryPredicate) функцию, которая удаляет элементы, которые удовлетворяют предикату.

Я написал следующий код на догадке, и, к удивлению, он работает:

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

В чем заключается магия next или pairs, которая позволяет этому коду работать.Насколько я вижу, он повторяет точно размер (aTable) раз.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Lua таблицы реализованы в основном как хеш-таблицы.В хеш-таблице хранится массив из (key, value) пар.

next использует хеш для быстрого перехода к тому месту, где они должны находиться в таблице.

Однако обратите внимание, что в реализации next есть проверка nil:

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

Это потому, что когда nil назначается ключу таблицы, он обновляет (ключ, значение) внутри хеш-таблицы, но на самом деле не удаляет эту запись.Таким образом, у вас остается (ключ, nil) запись в хеш-таблице.Этот дизайн позволяет итерации через next продолжать работу без изменений, когда существующим ключам присвоены значения, включая при назначении nil.

Однако это подробности реализации .Наличие или отсутствие записи nil в хеш-таблице полностью невидимо в API, предоставляемом реализацией таблицы.Каждая функция внешне обрабатывает эти nil клавиши точно так же, как и отсутствие.

0 голосов
/ 26 сентября 2018

next зависит только от ключей в таблице.Цикл удаляет значения, но не ключи (в текущей реализации Lua).В документации явно сказано, что вы можете удалять значения из таблиц в цикле, как у вас.В нем также говорится, что вы не можете добавлять новые записи с новыми ключами, именно потому, что это может сбить с толку next.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...