-
Число публикаций
618 -
Регистрация
-
Последнее посещение
-
Дней в топе
1 -
AMKoin
37 [Подарить AMKoin]
Весь контент пользователя Nazgool
-
-
Artos Что-то мы говорим на разных языках. Попробую ещё раз. По типу построения между этими таблицами нет никакой разницы. На самом деле они же выглядят так : {[1]='a', [2]='b', [3]='c', [4]='d'} и {[1]=1, [2]=5, [3]=2, [4]=4, [5]=3} Т.е. оператор # определит ВСЕ! поля этих таблиц. Если добавить в любой из списков поле, не соответствующее продолжению "списка", например {[1]='a', [2]='b', [3]='c', [4]='d', [7]='e'}, либо 'занилить' значение, после чего поле удалиться из списка {[1]='a', [2]='b', [3]=nil, [4]='d'}, то список перестанет быть таковым и станет хэшем на общих основаниях. Теперь оператор # определит в первом случае из 6-ти фактических полей только 5 (от индекса 1 до индекса 5). Во втором случае только 2 (т.к. поле с индексом 3 исчезло, и следующий индекс после 2 будет индекс 4), вместо фактических 3-х. !!! Для того, чтобы не нарушать строение таблицы как списка (который работает быстрее чем любой другой тип таблиц) нужно пользоваться специально созданными для этого функциями table.insert и table.remove, а не заниливанием и непонятно каким добавлением. Теперь о 'дырах' и собственно моем варианте без перебора. Имеется 3 типа таблиц : t1 = {a='p', k=6, [12]='s'} t2 = {'a', 'b', k=6} t3 = {'a', 8, 'c'} Хотя в таблице t2 и есть элеметы списка, но и она, и таблица t1 не являются списками. Это комбинированые хэш-таблицы. Получается что для списка нужно определить, равна ли длина таблицы фактическому количеству полей. Вот я и пошел таким путем. if #tаb~=0 Определяю, есть ли в таблице элементы списка (индексов от 1 и до упора). Если нет, то это уже не список. Ответ - хэш. Если есть такие элементы, то последний из них по любому найдется. И теперь проверяя nехt(tаb,#tа смотрю, есть ли за этим последним элементом списка ещё поля, характерные для хэша? Если нет (nil), то фактическая длина таблицы равна количеству полей, что означает одно - таблица является списком. Ну а если есть ещё поля, то это смешанная таблица, а по сути НЕ список. Добавлено через 48 мин.: В варианте с заниливанием внутри таблицы ([3]=nil) допустил неточность. Читать 'заниливанием извне', например t[3] = nil
-
Может я не так понял. Может вы имеете в виду таблицы с целочисленными индексами, но произвольными? Но ведь в условии были даны варианты таблиц именно индексируемые с 1 и по порядку.Все другие варианты рассматриваются как хэш-ы. С ними нельзя работать ни оператором #, ни table.concat. Также в условии стояла задача узнать тип таблицы. Я предложил вариант не только без пайрсов, но и без for i=1,#t. Условия выполнены. Что не так? Не пойму.
-
После if-а #t определит наличие/отсутствие ключей, начинающихся с 1 и до последнего целочисленного поступательно нарастающего. Если есть такие, то проверяем, есть ли ещё какие-либо записи (nехt). Если есть - значит хэш, если нет, то индексный массив. Прогоните код в SсiТЕ. Не пойму, чего вы хотите от iраirs? Всё происходит так как и положено. Какому-то индексу присвоили значение nil. Сборщик мусора удалил это поле. Осталось дырка в индексах. Вот он и тормознул на этом поле. Совершенно правильно работает.
-
Полагаю что это уже мелочи, учитывая сказанное мною слово "набросок". Тем не менее ты прав в плане сравнения с нулем. Проверку с nехt делать всё равно прийдется. Например если есть и индексы от 1 до ... и не натуральные индексы.
-
По поводу определения типа таблиц. Набросок без итераторов. Проверку на пустую таблицу и скорость не делал. function GetTabStatus(tab) if #tab ~= 0 and not next(tab, #tab) then return 'index' -- индексирудмый массив else return 'hash' -- всё подряд end end
-
Можно без '0x' (на всякий случай уточню) в чистом lua hex = string.format('%x', 65535) dec = tonumber(hex,16) Спасибо. Проверил: в игре такой вариант работает. --/ Artos
-
Я поленился на теле набирать, но ведь tonumber ещё не отменяли :-) dec = string.format('%d', tonumber('0x'..hex)) Или Сталкер и этого не понимает? К сожалению ... Метод 'tonumber' ожидает только десятичное представление числа символами строки. Любой не 'числовой' символ ('x') - воспринимается как буква и => 'nil'. --/ Artos P.S. Подзабыли про параметр '16' для метода ... :-)
-
Artos По первому вопросу боюсь что без перебора не получиться. В принципе есть идея чтобы не перебирать. Но это когда буду дома. По второму вопросу могу пока предложить string.format hex = string.format('%x', 65535) dec = string.format('%d', '0x'..hex) У меня есть доморощенная функция преобразования DЕС/НЕХ, но я сейчас с тела. Вечером сравню скорости и сообщу. Метод 'string.format('%d', '0x'..hex)' - не применим для игры, т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор) --/ Artos
-
Плз, покажи код, как создавала. Плз, покажи код как учила.
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Не один раз на разных форумах задавали вопрос о том что-же такое шаблон и с чем его едят. Совсем недавно подобный вопрос всплыл и тут. Вот и решил , за отсутствием специализированного топика по lua, выложить материал тут. Но прежде всего хочу сказать, что всё сказанное мною относиться к заре моего познавания Lua. Сейчас нет времени исправлять то, чего не знал, не так объяснил и не правильно понимал. Поэтому выкладываю как было на тот момент. Всё же лучше чем сухие предложения из официального мануала. С вопросами (а также тонкостями) составления шаблонов обращаться либо в ПМ, либо (лучше в плане всеобщего образования) в теме "Скриптование, спавн и логика ". Хватит лирики, вот ссылка на страничку из моего манула по Lua 2-x двухгодичной давности : http://ifolder.ru/25675390 -
Artos Мои результаты в тесте (пост #320 стр.16 "Справочника") говорят об обратном. Concat оказался быстрее. Не на много, но факт.
-
Artos Наверное следует вспомнить про дедушку Эйнштейна. Если смотреть относительно заранее проинициализированных строками переменных, то простая конкатенация конечно будет работать быстрее, чем tаblе.соnсаt, для использования которого необходимо понести накладные расходы на создание массива. Если же смотреть относительно заранее созданой таблицы с массивом конкатенируемых строк, то быстрее будет tаblе.соnсаt, т.к. расход понесет простая конкатенация, для выполнения которой нужно выбирать значения из таблицы. В общем нужно исходить из конкретных ситуаций.
-
singapur22 Поступил по твоей аналогии и заключил все варианты в функции. Оставил общую таблицу как "точку отсчёта".
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Изначально, вместо unpack я писал tb[1], tb[2], tb[3], tb[4], tb[5]. Результат был ещё хуже. Как бы ещё немного помог ей. P.S. Что-то мне подсказывает, что мы не в той теме общаемся. Нам бы в "Скриптование..." перейти. -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Теперь я забираю свои слова, сказанные выше, назад. Если поставить все тестовые варианты в равные условия, то результаты сильно изменяться. Изначально я создал таблицу строк, а потом использовал обращение к ней из каждого варианта. Для string.format создал идеальные условия, т.к. иначе проигрыш будет слишком очевиден. -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
singapur22 Вот спасибо. Теперь можно внести дополнение в определение - "При работе с заведомо длинными строками (100 и более символов) следует использовать string.format, который будет работать быстрее чем table.concat" -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Да, попробуйте сделать строки длиной по 99 символов (ужасная задержка), а затем по 100 (обыгрывает concat) и сравните результаты. Это только у меня format так себя ведет? -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
malandrinus, RvP По следам разбора конкатенации... Найду свободное время - поэкперементирую, но пока вот мои результаты в SciTE (??? не вписываются в заключение ???) : table 1.875 concat 0.344 format 1.5 Добавлено через 9 мин.: Ага. Увеличил размер строки и всё стало на свои места. malandrinus, удали пожалуйста мой пост. При разных длинах строк происходят совершенно интересные вещи. Разберу - отпишусь конкретнее. -
Artos Да я вот тоже до сих пор ломаю голову, зачем нужно вот это : elseif type(Mode) == "number" then --//таблица '[idx] = число или стринг' for sValue in sStr:gmatch(sPatt) do tRet[#tRet+1] = tonumber(sValue) or sValue end end
-
В любом справочнике по luа. В сети их не так уж и мало. Правда сухие фразы определений это плохой помощник для новичка. Может прийдет вдохновение - напишу подробнее. Добавлено через 308 мин.: Если расставлять приоритеты (в принципе), то борясь за каждую миллисекунду всякими контролями можно пренебречь. И если я сам пишу код, то наверняка знаю что, куда и как писать. И зачем мне думать, что кто-то там полезет в него и накосячит. Я, например, могу пожертвовать этим ради скорости. Не знают - нечего лезть. Т.е. вот это : local sPatt = '[%w%_]+' --/ дефолтный патерн (разделение по 'словам') --/ если задан сепаратор: разделяем по сепаратору if type(sDiv) == "string" then sPatt = '%s*([^'..sDiv..']+)%s*' --/ по разделителю (исключая начальные и заключительные пробелы) --/ если указан шаблон: используем шаблон elseif type(sPattern) == "string" then sPatt = sPattern end Я записал бы так (пусть, например, паттерн будет приоритетнее сепаратора): local sPatt = sPattern or sDiv and '%s*([^'..sDiv..']+)%s*' or '[%w%_]+' А если уж ставил бы проверки, то тотальные. Первой же строкой что-то типа : if not sStr then return '' end sDiv экранировать спец. символы (вдруг кто-то забыл, не знал) sPattern в локальной функции сделал бы проверку на корректность составления паттерна (то, что я до сих пор не внёс в script Syntax Checker)
-
Artos Вот что ты мне напомнил ненароком. Нужно внести эту информацию в справочник : coroutine не даёт возможности многопоточности. Подпрограммы выполнятся так же как и обычные функции - в одном потоке. А вот "размазать по времени" вполне можно.
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
По совету Artos-а решил изложить материал, касающийся работы с coroutine тут, поскольку данная таблица входит в пакет Lua СТАЛКЕР-а, и более подходящей темы трудно найти. Нужность/ненужность данной информации оставлю на рассмотрение malandrinus-а, т.к. практическое использование подпрограмм пока находится под большим вопросом. Тем не менее есть люди интересующиеся, поэтому продолжу... Итак, обо всё по порядку (malandrinus-у. Можно я буду писать частями? Хочется сделать не только информативно, но и придать внешний вид. А вот со свободным временем у меня не очень.) : ---------------------------------------------------------------------------------------------------------------------------------------- Операции для работы с подпрограммами собраны в виде подбиблиотеки базовой библиотеки и содержатся внутри таблицы coroutine. Эта таблица содержит всего шесть функций : create wrap resume yield status running Я их подразделяю на основные : create и wrap - создают подпрограмму resume - запускает или продолжает выполнение подпрограммы yield - приостанавливает выполнение подпрограммы И служебные : status - возвращает состояние подпрограммы running - возвращает саму подпрограмму Рассмотрим их подробнее. -
"Поисследовал" я это дело уже давно, только почему-то убедил себя в том, раз уж нет ни IО, ни DЕВUG, то и СОRОUTINЕ путь заказан. Тут получается так, что основная задача уже не сам факт возможности прерывания выполнения функции, а сохранение и восстановление (после загрузки например) текущего состояния и данных. Хорошо если эти данные простого типа (числа, стринги, булевы значения). А если данные какого-то объекта (или же сам объект), который на момент работы своей очереди выполнения подпрограммы существовал, потом был удалён? И при загрузке текущего состояния нужны будут либо сам объект, либо его данные? Короче, подумаю над этим. Про работу СОRОUTINЕ постараюсь сегодня рассказать подробнее.
-
Artos Не знаю, писать ли тутор, или по ходу дела будет видно. Coroutine мало кому известны, поэтому покажу как проверял, а потом уже, наверное, будут вопросы, ответы на которые и введут в курс дела. Хотя не уверен что кому-то понадобиться. Пошел по самому быстрому пути (несчастный bind_stalker ). Решил для наглядности прерывать цикл. В качестве "генератора" вызовов использовал не менее несчастный "update(delta)". Каждые 5 секунд прерывал работу цикла и затем снова продолжал: ..... co = coroutine.create(function (a) for i=1,10 do coroutine.yield(a+i) end end) local ttt = time_global() function actor_binder:update(delta) if time_global() - ttt >= 5000 then if coroutine.status(co) ~= "dead" then local _, result = coroutine.resume(co, 5) if result then news_manager.send_tip(db.actor, result) end end ttt = time_global()+5000 end ..... В результате каждые 5 секунд выводились сообщение 5,6,7,8 ... 15. Прошу заметить, что целью было не осуществление перебора (для этого есть более простые способы). Смысл coroutine в том, что (например) при первом обороте цикл останавливается, и ждёт до тех пор, пока не произойдёт следующий вызов. Игра идёт своим чередом дальше. и вызывать можно хоть отсюда. хоть из другого скрипта - не важно. Важно задать имя подпрограммы (co) глобально, чтобы была возможность последующего вызова из любого скрипта. Добавлено через 40 мин.: Забыл сказать, что на момент остановки можно получать текущие данные, а в момент запуска-продолжения передавать новые для обработки.
УЧИМСЯ МОДДИНГУ
ИГРАЕМ В МОДЫ НА ТЧ
ИГРАЕМ В МОДЫ НА ЧН И ЗП
- [ЧН] OGSM CS 1.8 CE Fixes
- [ЧН] HARDWARMOD 3.2
- [ЗП] The Long Road
- [ЧН] New vision of War
- [ЧН] Old Good Stalker Mod - Clear Sky
- [ЗП] Unofficial Patch
- [ЗП] Смерти вопреки
- [ЗП] Контракт на хорошую жизнь
- [ЗП] Shoker Weapon Mod 2.1
- [ЗП] Hardcore pack for SGM 2.2
- [ЗП] Контракт Синдиката
- [ЗП] Клондайк 2.0
- ...и другие моды
ПОЛЕЗНОЕ И РАЗНОЕ