Все посты %s в %S - AMK Team
Перейти к контенту

Язык Lua. Общие вопросы программирования


Malandrinus

Рекомендуемые сообщения

Есть ли в Lua возможность пропустить шаг в цикле? Приведу пример из php

foreach ($array as $k => $v ) {
   ...
   if (...) {
    continue // код ниже не будет выполнятся для текущей пары k,v
   }
   ...
}

Надеюсь, понятно объяснил

Поделиться этим сообщением


Ссылка на сообщение

Да это понятно. Только как раз наличие такого оператора дало бы возможность уменьшить вложенность, как ранний return в функции. Эх, жаль конечно.

Я тут недавно наткнулся на интересный вариант итерации таблиц table.foreach(table, function(k,v) ... end). Если пользоваться таким способом, то тут ранний return решает проблему вложенности. А вот как со скоростью по сравнению с pairs (ipairs)? Есть ли какие-нибудь подводные камни?

Поделиться этим сообщением


Ссылка на сообщение

В ЗП эта функция есть, и раз нет ничего такого, чтобы мешало её использовать, отныне буду все итерации таблиц делать с её применением, чтобы код выглядел более читабельным.

 

Дабы не разводить чат в теме пишу в твоём же посте (эх, служебное положение).

Не соглашусь с тем, что функция итератор foreach выглядит более читабельно нежели pairs.

Но, раз тебе нравится - пожалуйста, никто собственно и не возражает...

ColR_iT

Изменено пользователем ColR_iT

Поделиться этим сообщением


Ссылка на сообщение

Приведу пример, что для меня значит "читабельность" кода. Фрагмент из treasure_manager.script (ТЧ)


for k,v in pairs(self.treasure_info) do
if v.done == false then
local treasure_prob = xr_logic.pick_section_from_condlist(db.actor, npc, v.condlist)

if treasure_prob == "" or treasure_prob == nil then
treasure_prob = 0
end

if tonumber(treasure_prob) >= 0 and
v.community[npc:character_community()] == true and
v.active == false
then
if tonumber(treasure_prob) == 100 then
self:give_treasure(k)
else
table.insert(avail, {k = k, prob = treasure_prob})
tr_sum = tr_sum + treasure_prob
end
end
end
end

 


table.foreach(self.treasure_info, function(k,v)
if v.done then return end

local treasure_prob = xr_logic.pick_section_from_condlist(db.actor, npc, v.condlist)

if treasure_prob == "" or treasure_prob == nil then
treasure_prob = 0
end

if tonumber(treasure_prob) == 0 or not v.community[npc:character_community()] or v.active then
return
end

if tonumber(treasure_prob) == 100 then
self:give_treasure(k)
else
table.insert(avail, {k = k, prob = treasure_prob})
tr_sum = tr_sum + treasure_prob
end
end)

 

 

P.S. Использование функции table.foreach случайно обнаружил в файле .script распакованной геймдаты ТЧ

Поделиться этим сообщением


Ссылка на сообщение

Как раз в приведённых мною примерах я вообще не уделил внимание корректности и оптимальности, а только показал, как с помощью table.foreach можно избавиться от вложенности. Что конкретно происходит внутри цикла - я даже не вникал. Так что по пунктам 1,2 и 3 - это к GSC :)

Изменено пользователем ColR_iT

Поделиться этим сообщением


Ссылка на сообщение

Проверил для ЗП 1.6.2 + X-Ray extension, результаты:

pairs: 0.162835 sec

foreach: 0.698536 sec

Достаточно убедительный довод, чтобы впредь не использовать foreach. Жаль конечно :(

Поделиться этим сообщением


Ссылка на сообщение

Когда я первый раз запускал эксперимент, то подумал об этом, и создавал три разных "счётчика", поэтому у меня результаты не изменились:

##time is 162232.109375

##time is 731144.5

##time is 566500.8125

 

PS: Результаты сильно разнятся, интересно, с чем это связано? У меня процессор Intel Core Duo T8100 2.10Ghz. А может из-за версии игры?

Изменено пользователем Shredder

Поделиться этим сообщением


Ссылка на сообщение

У меня в ЗП наоборот a = t.id выигрывает по скорости у a = t['id'], не в разы конечно, а процентов 10-15.

Поделиться этим сообщением


Ссылка на сообщение

Поэтому, если вызвать функцию из примера просто как is_wounded(...), то эта функция будет и запрашиваться из таблицы _G.

 

Там такой нет. Вылет.

 

Я видимо что-то не понимаю. Сперва поиск функции будет осуществляться в текущем модуле (_M), там она есть. От куда вылет?

Поделиться этим сообщением


Ссылка на сообщение

Если меняются только аргументы, так для каждой функции и создавай таблицу этих параметров:

tbl = {}

function Past(f,v)
    if not tbl[f] then
        tbl[f] = {}
    end
    table.insert(tbl[f], v)
end

function OnPrint()
    func2 = func
    func3 = func
    Past (func2, "two")
    Past (func3, "three")
    for fun,vals in pairs (tbl) do
        for i,val in pairs(vals) do
            fun(val)
        end
    end
end
Извиняюсь, если не уловил суть вопроса.

Поделиться этим сообщением


Ссылка на сообщение

Я уже давно использую функционал xr_s.script, хотя и немного правленый для моих целей, но мне не разу не приходилось регистрировать одну и ту же функцию несколько раз. Можешь привести практический пример, для чего это нужно?

Поделиться этим сообщением


Ссылка на сообщение

Можешь написать, в чём профит продвинутых систем? Глянул описание. В "Песочнице" принципиальной разницы не увидел, разве что пара плюшек (e:stop(), e:removeThisCallback()), но у меня такой надобности не возникало. В ogse_signals принцип регистрации практически тот же, про слоты не понял.

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...