Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> lua, таблица, вызов функции, Отбросить в функции последнее поле таблицы
фонарик
сообщение 7.4.2021, 1:42
Сообщение #1


****

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)
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 7.4.2021, 2:10
Сообщение #2


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26540
Пользователь №: 16.971
Возраст: 29



Лучше напишите что вообще хотите сделать.
table не самое лучше имя для таблицы, оно хоть и не зарезервировано, но может привести к ошибке.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
фонарик
сообщение 7.4.2021, 4:00
Сообщение #3


****

Apprentice
Сообщений: 145
Регистрация: 23.11.2011
Группа: Пользователи
Наличность: 0
Пользователь №: 14.305



Я пытаюсь при помощи вашего плагина Prompt пообщаться с пользователем. Выдать ему иерархическое дерево с разделами, подразделами, подподразделами, что, в конечном итоге, должно привести к конечному значению, которое дальше должно быть использовано в скрипте.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 7.4.2021, 10:13
Сообщение #4


***********

Модератор 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____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
фонарик
сообщение 7.4.2021, 14:12
Сообщение #5


****

Apprentice
Сообщений: 145
Регистрация: 23.11.2011
Группа: Пользователи
Наличность: 0
Пользователь №: 14.305



Пользователь путем многоуровневого Prompt (выбор с каталогами, подкаталогами и так далее) взаимодействует с функцией, в которую передаёт свой выбор. Функция принимает значения и выдает варианты выбранного ранее. В эту сторону вроде как проблем нет, но необходимо чтобы пользователь мог вернуться назад, к предыдущему выбору. Вот здесь засада.

Пытался найти инфу как узнать имя таблицы, значения которой передаются в функцию. Но то ли функции придумали контрабандисты, полагающие, что лишняя инфа ей только навредит, то ли я просто не нашёл то что искал. Но самая беда в том, что я даже не знаю что погуглить. Вы правильно заметили, проблема с подходом. Я бы и рад его пересмотреть - но подглядеть некуда (IMG:style_emoticons/default/unsure.gif)
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Madeus
сообщение 7.4.2021, 14:35
Сообщение #6


****

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

Помойму тебе проще сделать несколько разных таблиц
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Madeus
сообщение 7.4.2021, 15:10
Сообщение #7


****

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))


Исправил
Пользователь в онлайне!Delete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
фонарик
сообщение 7.4.2021, 17:52
Сообщение #8


****

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["Месяц"]["Март"] отсутствует как таблица), то нужно из функции вернуть это конечное значение "Март".
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 8.4.2021, 3:58
Сообщение #9


**********

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
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
фонарик
сообщение 9.4.2021, 21:41
Сообщение #10


****

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)
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 10.4.2021, 2:24
Сообщение #11


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26540
Пользователь №: 16.971
Возраст: 29



Цитата
prev = t
n = h.lua_prompt(t)
t = t[t[n]]

После этого уже не существует изначальной таблицы t, точнее пока что она в prev, но потом значение этой переменной тоже изменится и по сути возвращаться некуда будет, только на 1 шаг назад.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 10.4.2021, 5:47
Сообщение #12


***********

Модератор 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____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Fors1k
сообщение 10.4.2021, 17:14
Сообщение #13


*****

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
Два

Во втором случае данные исходного массива не изменились.


--------------------
Для связиИзображение
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 10.4.2021, 18:13
Сообщение #14


***********

Модератор UOPilot
Сообщений: 9.460
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27708
Пользователь №: 11.279



Прям напрямую - нет, копировать нельзя. Обычно вот этого достаточно:
Код
function table.clone(org)
  return {table.unpack(org)}
end

хотя есть гораздо более грамотные решения и достаточно объемные.


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 10.4.2021, 18:23
Сообщение #15


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26540
Пользователь №: 16.971
Возраст: 29



Цитата
table.unpack(org)

Код
unpack(org)
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 10.4.2021, 18:54
Сообщение #16


***********

Модератор UOPilot
Сообщений: 9.460
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27708
Пользователь №: 11.279



Цитата
table.unpack(org)

Код

unpack(org)

Копипастил) Я этот код не юзаю - у меня комбайн. Копирую редко, но вышеуказанный метод имеет ограничения. На те же метатаблицы.


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
фонарик
сообщение 10.4.2021, 22:06
Сообщение #17


****

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 стал неким аналог истории, который впитал в себя таблицы, в которых пользователь сделал выбор.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Fors1k
сообщение 10.4.2021, 22:21
Сообщение #18


*****

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


--------------------
Для связиИзображение
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия | Версия для КПК Сейчас: 28.3.2024, 20:32
Designed by Nickostyle