|
|
|
lua, таблица, вызов функции, Отбросить в функции последнее поле таблицы |
|
|
фонарик |
7.4.2021, 1:42
|
Apprentice
Сообщений: 145
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 0
Пользователь №: 14.305
|
Код --lua table = {'Год', 'Месяц', 'День'} table["Год"] = {'2020', '2021', '2022'} table["Месяц"] = {'Январь', 'Февраль', 'Март'} table["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер'} table["Месяц"]["Февраль"] = {'Вечер'}
function DATA(tbl) NewDATA = table["Месяц"]["Январь"] -- как отбросить ["Январь"] ? return NewDATA end
e = DATA(table["Месяц"]["Январь"]) msg(unpack(e)) В функцию DATA передается таблица table["Месяц"]["Январь"]. Т.е 3 значения: 'Утро', 'День', 'Вечер'. Как в функции обрезать последнее поле ["Январь"] ? Чтобы функция вернула table["Месяц"] ? Т.е значения 'Январь', 'Февраль', 'Март' ? (IMG: style_emoticons/default/unsure.gif) Подскажите пожалуйста (IMG: style_emoticons/default/beg.gif)
|
|
|
|
DarkMaster |
7.4.2021, 10:13
|
Модератор UOPilot
Сообщений: 9.460
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 27708
Пользователь №: 11.279
|
Цитата table не самое лучше имя для таблицы, оно хоть и не зарезервировано, но может привести к ошибке. Пилотом может и не зарезервировано, а вот в луа является таблицей функций для работ с таблицами: table table.concat table.insert table.maxn table.remove table.sort Если совсем проще - эпик фейл. Так делать нельзя. По озвученному вопросу - передвать в функцию table["Месяц"] и отдельно ключ Январь. То, что вы хотите сделать идейно очень сильно ошибочно. Получая в функцию элемент таблицы, функция вообще не в курсе, что это элемент чего-то там и таблицы ли вообще. Подобное можно провернуть через debug, с некоторыми оговорками, но debug официально заявлен, как недопустимый для использования в ходе работы программы, а его использование разумно исключительно для отладки. По сути это нарушение инкапсуляции. Так же насколько мне известно lua относительно дырявенький в этом плане и его можно разломать методами самого луа, тем более имея на вооружении ffi. Тем не менее это путь вникуда. Настоятельно рекомендую пересмотреть данный подход. Сообщение отредактировал DarkMaster - 7.4.2021, 11:00
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
фонарик |
7.4.2021, 14:12
|
Apprentice
Сообщений: 145
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 0
Пользователь №: 14.305
|
Пользователь путем многоуровневого Prompt (выбор с каталогами, подкаталогами и так далее) взаимодействует с функцией, в которую передаёт свой выбор. Функция принимает значения и выдает варианты выбранного ранее. В эту сторону вроде как проблем нет, но необходимо чтобы пользователь мог вернуться назад, к предыдущему выбору. Вот здесь засада. Пытался найти инфу как узнать имя таблицы, значения которой передаются в функцию. Но то ли функции придумали контрабандисты, полагающие, что лишняя инфа ей только навредит, то ли я просто не нашёл то что искал. Но самая беда в том, что я даже не знаю что погуглить. Вы правильно заметили, проблема с подходом. Я бы и рад его пересмотреть - но подглядеть некуда (IMG: style_emoticons/default/unsure.gif)
|
|
|
|
Madeus |
7.4.2021, 14:35
|
Apprentice
Сообщений: 282
Регистрация: 19.11.2019 Группа: Пользователи Наличность: 8296
Пользователь №: 19.451
Возраст: 32
|
Цитата(фонарик @ 7.4.2021, 14:12) Пользователь путем многоуровневого Prompt (выбор с каталогами, подкаталогами и так далее) взаимодействует с функцией, в которую передаёт свой выбор. Функция принимает значения и выдает варианты выбранного ранее. В эту сторону вроде как проблем нет, но необходимо чтобы пользователь мог вернуться назад, к предыдущему выбору. Вот здесь засада. Пытался найти инфу как узнать имя таблицы, значения которой передаются в функцию. Но то ли функции придумали контрабандисты, полагающие, что лишняя инфа ей только навредит, то ли я просто не нашёл то что искал. Но самая беда в том, что я даже не знаю что погуглить. Вы правильно заметили, проблема с подходом. Я бы и рад его пересмотреть - но подглядеть некуда (IMG: style_emoticons/default/unsure.gif) В твоем случае "Месяц" это не имя таблицы, а ключ с именем "Месяц" в таблице table "тавтология" и да так делать не стоит) По факту твоя структура имеет следующий вид Код --lua t = { [1] = 'Год', [2] = 'Месяц', [3] = 'День', ["Год"] = { '2020', '2021', '2022' }, ["Месяц"] = { [1] = 'Январь', [2] = 'Февраль', [3] = 'Март', ["Январь"] = { 'Утро', 'День', 'Вечер' }, ["Февраль"] = { 'Вечер' } }, }
for k,v in pairs(t) do log(k) end
Помойму тебе проще сделать несколько разных таблиц
|
|
|
|
Madeus |
7.4.2021, 15:10
|
Apprentice
Сообщений: 282
Регистрация: 19.11.2019 Группа: Пользователи Наличность: 8296
Пользователь №: 19.451
Возраст: 32
|
Вроде работает Код --lua t = {'Год', 'Месяц', 'День'} t["Год"] = {'2020', '2021', '2022'} t["Месяц"] = {'Январь', 'Февраль', 'Март'} t["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер'} t["Месяц"]["Февраль"] = {'Вечер'}
function DATA(tbl) local t2 = tbl or t for k,v in pairs(t) do if v == t2 then NewDATA = t return NewDATA end if type(v) == 'table' then for n, m in pairs(v) do if m == t2 then NewDATA = t[k] return NewDATA end end end end return t2 end
e = DATA(t["Месяц"]["Январь"]) msg(unpack(e))
Исправил
|
|
|
|
фонарик |
7.4.2021, 17:52
|
Apprentice
Сообщений: 145
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 0
Пользователь №: 14.305
|
Madeus, да, вот то что я задумывал, но к сожалению сам так и не осилил. К тому же, пока что многочасовые попытки понять механику вашего варианта, как вы это сделали, пока тщетны. И применить для свой задачи не получается (IMG: style_emoticons/default/sad.gif) Не могли бы вы свой вариант адаптировать под конкретный случай? У товарища cirus в разделе " Плагины и доп. ПО" есть плагин для команды Prompt. Я пытаюсь выдать пользователю структурный выбор с возможностью возвращаться назад. Код lua
Код --lua h = require'prompt' t = {'Год', 'Месяц', 'День', 'стоп'} t["Год"] = {'2020', '2021', '2022', 'назад', 'стоп'} t["Месяц"] = {'Январь', 'Февраль', 'Март', 'назад', 'стоп'} t["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер', 'назад', 'стоп'} t["Месяц"]["Февраль"] = {'Вечер', 'назад', 'стоп'}
function DATA(tbl) local t2 = tbl or t for k,v in pairs(t) do if v == t2 then NewDATA = t return NewDATA end if type(v) == 'table' then for n, m in pairs(v) do if m == t2 then NewDATA = t[k] return NewDATA end end end end return t2 end
local handle = windowfromcursor() workwindow(handle) local x, y, width, height, errorcode = windowpos (handle) local HintX = width / 3 + x - 100 local HintY = height + 200 h.promptposX = HintX h.promptposY = HintY
::UserPrompt:: param, EndValue = DATA(param) h.lua_prompt(param)
if not EndValue then goto UserPrompt else goto FieldData end
::FieldData:: msg(EndValue) stop_script() Пункт 'назад' (может отсутствовать) всегда предпоследний, 'стоп' последний. Если у выбора нет дальнейшей иерархии, Например, пользователь выбрал Месяц => Март (т.е t["Месяц"]["Март"] отсутствует как таблица), то нужно из функции вернуть это конечное значение "Март".
|
|
|
|
cirus |
8.4.2021, 3:58
|
Elder
Сообщений: 3.480
Регистрация: 18.8.2014 Группа: Пользователи Наличность: 26540
Пользователь №: 16.971
Возраст: 29
|
Суть примерно такая, остальное по аналогии. Код --lua local h = require'prompt'
local t = {'Год', 'Месяц', 'День', 'стоп'} t["Год"] = {'2020', '2021', '2022', 'назад', 'стоп'} t["День"] = {'Понедельник', 'Вторник', 'назад', 'стоп'} t["Месяц"] = {'Январь', 'Февраль', 'Март', 'назад', 'стоп'} t["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер', 'назад', 'стоп'} t["Месяц"]["Февраль"] = {'Вечер', 'назад', 'стоп'}
log 'clear' log 'mode compact'
local result = h.lua_prompt(t) if t[result] == nil or t[result] == 'стоп' then end_script() else result = h.lua_prompt(t[t[result]]) log( result ) end
|
|
|
|
фонарик |
9.4.2021, 21:41
|
Apprentice
Сообщений: 145
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 0
Пользователь №: 14.305
|
lua
Код --lua local h = require'prompt'
t = {'Год', 'Месяц', 'День', 'стоп'} t["Год"] = {'2020', '2021', '2022', 'назад', 'стоп'} t["День"] = {'Понедельник', 'Вторник', 'назад', 'стоп'} t["Месяц"] = {'Январь', 'Февраль', 'Март', 'назад', 'стоп'} t["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер', 'назад', 'стоп'} t["Месяц"]["Февраль"] = {'Вечер', 'назад', 'стоп'}
log 'clear' log 'mode compact'
function MyPrompt (t, n, prev)
n = h.lua_prompt(t)
if type(t[t[n]]) == 'table' then prev = t t = t[t[n]] return t, n, prev else
if t[n] == 'назад' then t = prev return t, n, prev end
if t[n] == 'стоп' then end_script() end
t = t[n] return t end
end
prev = t n = h.lua_prompt(t) t = t[t[n]]
::u::
t, n, prev = MyPrompt (t, n, prev)
if type(t) == 'table' then goto u else msg(t) end_script() end
Опилки от шевеления почти возгорались, 2 раза бросал, но возвращался (IMG: style_emoticons/default/smile.gif) Сложность с пунктом "назад". Я придумал передавать в функцию предыдущую таблицу. Но беда в том, что нужно иметь возможность не только вернуться к предыдущему выбору, но и к тому что был перед ним. Грубо говоря, углубился в список, а потом жмём 2 раза назад или 3, чтобы выйти к корню списка. Или всё это совсем не та аналогия вышла (IMG: style_emoticons/default/unsure.gif)
|
|
|
|
DarkMaster |
10.4.2021, 5:47
|
Модератор UOPilot
Сообщений: 9.460
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 27708
Пользователь №: 11.279
|
Цитата После этого уже не существует изначальной таблицы t, точнее пока что она в prev, но потом значение этой переменной тоже изменится Я долго пытался понять, как мне кажется речь о том, что таблицы в луа не копируются. Т.е.: t = {123} t2 = t На самом деле здесь ни t ни t2 не являются таблицами. При объявлении таблицы {123}, создается таблица (кто бы мог подумать), но вот присваивается в t уже не таблица а ссылка на нее. В дальнейшем когда мы производим t2=t, то на самом деле мы просто копируем ссылку/указатель на эту таблицу. Поэтому если мы сделаем, скажем: t2[1] = 0 то t[1] так же станет равно 0
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Fors1k |
10.4.2021, 17:14
|
Journeyman
Сообщений: 497
Регистрация: 19.12.2017 Группа: Пользователи Наличность: 2420
Пользователь №: 18.746
|
Цитата(DarkMaster @ 10.4.2021, 5:47) таблицы в луа не копируются
Так во всех языках (почти). Это называется примитивные и ссылочные типы данных. Для копирования данных ссылочного типа используются методы самого объекта, или статические методы соответствующего класса. Как я понял, в луа нет методов копирования объектов. Для наглядности приведу пример как обычно выглядит копирование данных ссылочного типа: code
--lua log"clear";log"mode compact";require"luaposh"
PScode('r',{[[#} # log "Присвоение:`n" # создаем массив $array_A = 1, "Два" # записываем ссылку на массив в новую переменную $array_B = $array_A # изменяем данные $array_B[0] = 888 # проверяем данные в исходном массиве log $array_A
log "`nКопирование:`n" # создаем массив $array_C = 1, "Два" # создаем копию массива $array_D = $array_C.Clone() # изменяем данные $array_D[0] = 888 # проверяем данные в исходном массиве log $array_C # ]]}) Log: Код Присвоение:
888 Два
Копирование:
1 Два Во втором случае данные исходного массива не изменились.
--------------------
Для связи
|
|
|
|
фонарик |
10.4.2021, 22:06
|
Apprentice
Сообщений: 145
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 0
Пользователь №: 14.305
|
(IMG: style_emoticons/default/yahoo.gif) (IMG: style_emoticons/default/yahoo.gif) (IMG: style_emoticons/default/yahoo.gif) lua
Код --lua local h = require'prompt'
t = {'Год', 'Месяц', 'День', 'стоп'} t["Год"] = {'2020', '2021', '2022', 'назад', 'стоп'} t["День"] = {'Понедельник', 'Вторник', 'назад', 'стоп'} t["Месяц"] = {'Январь', 'Февраль', 'Март', 'назад', 'стоп'} t["Месяц"]["Январь"] = {'Утро', 'День', 'Вечер', 'назад', 'стоп'} t["Месяц"]["Февраль"] = {'Вечер', 'назад', 'стоп'}
log 'clear' log 'mode compact'
function MyPrompt (t, n, prev)
n = h.lua_prompt(t)
if type(t[t[n]]) == 'table' then if prev[#prev] ~= t then prev[#prev+1] = t end t2 = t[t[n]] return t2, n, prev else
if t[n] == 'назад' then if #prev > 1 then t2 = prev[#prev] table.remove(prev)
return t2, n, prev end t2 = prev[#prev] return t2, n, prev end
if t[n] == 'стоп' then end_script() end
t2 = t[n] return t2 end
end
prev = {t} n = h.lua_prompt(t) t = t[t[n]]
::u::
t, n, prev = MyPrompt (t, n, prev)
if type(t) == 'table' then goto u else msg(t) end_script() end
Действительно, изначальную таблицу t нельзя трогать (IMG: style_emoticons/default/smile.gif) А prev стал неким аналог истории, который впитал в себя таблицы, в которых пользователь сделал выбор.
|
|
|
|
Fors1k |
10.4.2021, 22:21
|
Journeyman
Сообщений: 497
Регистрация: 19.12.2017 Группа: Пользователи Наличность: 2420
Пользователь №: 18.746
|
фонарик, обрати внимание на еще одну особенность. К сожалению, в луа переменные по умолчанию создаются в глобальной области видимости, так что при инициализации переменной внутри функции, нужно использовать модификатор local, чтобы она не существовала за ее пределами. Пример: --lua log "clear";log "mode compact"
t = {}
function set(n) local m = n * 2 return m end
t[1] = set(5) log(t[1]) Сообщение отредактировал Fors1k - 10.4.2021, 22:35
--------------------
Для связи
|
|
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|