Перейти к контенту

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


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

С чего начинать и где взять.

 

Установка Lua:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106

 

Руководство «Программирование на языке Lua», третье издание:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308

Изменено пользователем Kirgudu
Ссылка на комментарий

malandrinus, согласен с замечанием про t1000s, это уже из темы "раз есть ошибка - гадаем на всем что к ней может относиться".

Насчет "и та и другая часть в таблице присутствуют всегда" - это несколько перебор, т.к. "часть с интексом" может отсутствовать.Пример: пустая таблица не имеет ни одной части, пример2: {k1=v1,k2=v2,...} при k1 ~= 1, и т.п. Т.е. любая таблица с t[1]==nil - может иметь только хеш-часть, хотя ... можно и говорить "а почему индекс только в единицы? должен начинаться" ...

Если таблица имеет вид {v1,v2,...} и подразумевается, что ни одно поле не пустое - наверное правомочно говорить именно о не-хеш таблице, а о индексированной. Кому такое не по вкусу, то следует избавиться от употребления table.insert/remove и #.

 

Собственно не столь о строении таблиц затеян разговор, а о допустимости/целесообразности применения именно методов для таблиц с индексами.

Категоричное отрицание этого для любых, ИМХО, неверно, и обедняет как коды самого программиста, так и нередко идет вразрез с оптимизацией кода.

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

Ну а если возникли ошибки при использовании индексированной части - то это повод или искать и исправлять ошибку или перейти полностью на методы с хеш-частями.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Продолжаем разговор про таблицы.

 

Вот код:

function test_tbl()
    local t, s = {}, 0
    for i = 1, 10 do t[i] = i end
    table.remove( t, 10 )
    t[10] = 10
    table.remove( t, 10 )
    _util["list_tbl"]( t, "test_tbl" )
end

(list_tbl - там много всякого, но, в общем, классическое for k,v in pairs(t) do ... end)

 

Вот конечный результат:

1, value: 1

....

8, value: 8

10, value: 10

9 records in table [test_tbl] ( # возвращает 8, что логично. )

 

Промежуточные - 10(10), 9(9), 10(10)

 

То есть, либо table.insert()/table.remove() - кстати, in pairs()/next() не гарантируют последовательности 1, 2 ... - либо - все остальное.

 

Artos, по поводу того, что в соли "очень много" всего - я бы даже жесче сказал. Приводим в порядок потихоньку.

Upd: да нет, я уже не сетую. Просто чтобы исключить другие причины. И, да, вот конкретно такой результат - он, все-таки, несколько удивляет. Скажем, я бы понял вылет с грохотом, или 1,2...9,10 (то есть, несработавшее вообще удаление).

 

Gun12, в смысле, код попробован на чистом lua, и конечный результат: 1, 2, ... 8, 9 ?

 

Upd2: проверил на меньших значениях: в сталкерском lua то же самое - рушится. Со SciTE, похоже, действительно, разница в реализациях. Ну и аминь. В принципе, имеет право - отрицать глупо, бессмысленно, и ничего не изменит.

 

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Dennis_Chikin

С точки зрения lua код абсолютно нормальный. И результаты получаются правильные.

Т.е. количество полей - 9, индексы от 1-го до 9-и включ.,значения тоже.

Единственное что может его "портить", это _util["list_tbl"]( t, "test_tbl" ).

Тем более ты писал, - "(list_tbl - там много всякого...)"

Ну или пресловутая "аномальность" lua версии Сталкер.

Изменено пользователем Gun12
Ссылка на комментарий

Dennis_Chikin, совершенно верно, итерация при помощи pairs не то что не гарантирует, а даже не предусматривает какую либо последовательность. Как в данный момент "карта легла" - так и выдает из таблицы. Это один из минусов пи пользовании такими таблицами и склоняет порою чашу весом именно на индексированные.

 

Однако, к чему эти коды? Повторю, почему, применяя методы именно для хеш-таблиц, ты все одно используешь удаление как для индексированных и продолжаешь упорно сетовать? Сравни:

function test_tbl()
  local t, s = {}, 0
  for i=1, 10 do
    table.insert( t, i ) --/ каждое значение добавляется в конец таблицы
  end
  table.remove( t, 10 ) --/ удаляется поле под 10-ым индексом
  table.insert( t, 10 ) --/ добавляется 10-ка в конец таблицы
  table.remove( t, 10 ) --/ удаляется поле под 10-ым индексом
  --/ ...
end

- и НИКАКИХ пробелов (потерь значений) в индексах.

Повторю, если используешь именно свойства индексированной таблицы - то обеспечь работу с этой таблицей именно как с индексированной, а не хеш-таблицей.

Ну а насчет солянки: все же не вправе жестко высказываться, трудов многие положили немало и это уже одно заслуживает уважения. А вот то, что ее в порядок приводить нужно "

потихоньку" - вот с этим не соглашусь. В ней (ИМХО) требуется кардинально заменить многое и не потихоньку, а сразу, т.к. тягомотина в конце концов приведет к тому, что энтузиазм улетучится а в сухом остатке так и будет ... сырая солянка.

 

 

Добавлено через 1 мин.:

Gun12, нет _util["list_tbl"]( t, "test_tbl" ) тут не при чем ...

Просто вроде как банальное t[10] = 10 на самом деле не в конец таблицы (на десятый индекс) добавляет, а уже в хеш-часть, разбивая таблицу на два типа.

А вот table.remove( t, 10 ) и даже table.remove( t, 11 ) - удаляет поле с ПОСЛЕДНИМ индексом, а это как раз 9-ка.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Да, пробовал в SciTE.

И индексация последовальная от 1=1, ... ,9=9. Как, собственно, и должно быть.

Ещё раз скажу, показанный тобою пример не портит массив, как последовательность поступательно-возрастающих, целочисленных индексов, начинающихся с единицы (и ещё раз повторю - в нормальном lua).

Artos

Я беру только данный пример.

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

Изменено пользователем Gun12
Ссылка на комментарий

Gun12, Gun12

Я пробую как миниум именно на компиляторе игры (SciTE- это в черне), поэтому и результат именно таков, каков он в игре.

Про некоторые особенности именно сталкеровского Lua мы уже гвоворили (вспомним arg.n ...) Вот и тут, table.remove( t, NN ) - удаляет не именно индекс NN, а если отсутствует, то первый имеющийся до него. Ну и t[10] = 10 - именно разбивает таблицу на две части разного типа, а не вроде как продолжает последовательную индексацию.

 

Добавлено через 8 мин.:

Gun12, говорим о том, что в солянке используются таблицы. Эти таблицы заполняются способом для хеш-таблиц, хотя и упорядоченной индексацией: for i = 1, 10 do t = i end. Далее, из этих таблиц удаляются некоторые индексы методом table.remove.

Ну и ... как говорит Dennis_Chikin, таблицы начали сыпаться ... Возникло подозрение, что виноват именно table.remove.

Так вот, если у них в моде хоть где-то после создания и удаления хоть раз проскакивает t[10] = 10 - то и не удивительно ... т.к. таблица уже НЕ чисто индексная и начинается удаление того, чего и не подразумевается.

Т.е. на примере данного кода, поле под индексом 9 вроде как и не удалялось, но из таблицы оно исчезло, что и приводит к путанице.

 

Dennis_Chikin, не используй добавление таблицы по ключам (что меняет структуру таблицы!), хотя и это вроде как и удобно - и не будет проблем.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Во всех учебниках, по которым я изучал lua, пишут, что lua до последнего старается сохранять массив именно как массив,а не как хэш.

Что и показывают результаты SciTE.

А вот что с подобным делает сталкер, можно только мягко назвать камасутрой.

Ссылка на комментарий

Gun12, но мы в форуме именно по Сталкеру и имеем то, что дадено. <_<

И хотя общие правила не должны нарушаться, но и против исключений бесполезно трепыхаться, сколь мы не кривили бы ... лицо.

Ну и, как ранее говорилось - кто выбырает 'безопасные' для себя варианты, отметая "подозрительные", а кто, балансируя между правилами и исключениями использует всю оставшуюся палитру методов.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos, см. выше апдейт 2:

10 или не 10 - не влияет. Да хоть 3 всего. А вот для случая с одной - двумя записями - сейчас тоже проверю. Уже интересно стало.

 

Gun12, там в начале разговора было резюме: исходя из описания lua - не от ПЫС, а от создателей собственно языка, сталкеровкий lua на такую камасутру право, увы, имеет. (Хотя это, конечно, ближе к буквоедству - "делаем так, по тому, что явно не запрещено", чем к рациональному.)

 

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Тогда дайте хоть постебаться:)

Для тех кому ну очень уж хочется добавлять элементы в таблицу методом t[k]=v

mt={__newindex = function(t,k,v) table.insert(t,k,v) end}
local t={}
setmetatable(t,mt)

t[1]=1
t[2]=2
t[3]=3
t[4]=4
...

Ссылка на комментарий

Dennis_Chikin

Чтобы как то закругляться:

Создавая таблицу и используя не: for i=1, NN do table.insert( t, i ) end , а for i = 1, NN do t = i end - мы в цикле(!) получаем целостную таблицу подчиняющуюся всем правилам для индексированной таблицы.

Oднако(!), стОит только добавить еще одно значение таким методом: t[NN+1] = NN+1 - то тут же любое обращение к такой таблице показывает, общий об'ем вроде как NN+1, но(!) при использовании table.remove( t, NN+1 ) - удаляется не NN+1, а именно NN, т.е. тот (последний) индекс, который был в изначальной индексированной части.

Т.е. именно для игры резюме таково: любое добавление (не в цикле) в конец таблицы (или за него) методом t[#t+1] = val - разбивает таблицу на две части разного типа и применение table.remove допустимо только к индексированной части таблицы.

Если ты будешь использовать методы только table.remove/insert - то никаких коллизий с таблицей не происходит.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Доброго времени суток.

Наверное, это более подходящая тема. С темой сталкера вопрос связан косвенно, но к самой игре не имеет отношения.

Вопрос наверное простоват, но я что-то не могу понять (пока только учусь).

 

Имеется три таблицы, из первой берется рандомная строка, далее, необходимо условие: если эта строка равна какой-либо строке из второй таблицы, то, к возвращаемой строке, добавляется строка из третьей таблицы, а если не равно, то ничего не добавляется. Так вот, собственно, не могу понять, как провести сравнение Text_1 с со второй таблицей?

Дайте пожалуйста пинка в нужном направлении.

 

function Initialize()
table_1={
"String_1",
"String_2",
"String_3",
"String_4",
"String_5",
"String_6",
"String_7",
"String_8",
"String_9",
"String_10"
}

table_2={
"String_1",
"String_4",
"String_7",
"String_10"
}

table_3={
"String_1a",
"String_2a",
"String_3a",
"String_4a",
"String_5a",
"String_6a",
"String_7a",
"String_8a",
"String_9a",
"String_10a"
}
end

function Update()
Text_1 = table_1[math.random( #table_1 )]
    if Text_1 == table_2 then
        Text_2 = table_3[math.random( #table_3 )]
    end

    if Text_1 ~= table_2 then
        Text_2 = " "
    end
    
return  Text_1.." "..Text_2
end

 

Если важно, то это для программы Rainmeter.

 

userbar368.png

Ссылка на комментарий

Callisto

Если по-быстрому, то можно

Измени таблицу

table_2 = {
["String_1"] = true,
["String_4"] = true,
["String_7"] = true,
["String_10"] = true
}

И функцию

function Update()
    local txt = table_1[math.random( #table_1 )]
    if table_2[txt] then
        txt = txt.." "..table_3[math.random( #table_3 )]
    end
    
    return  txt
end

 

Ссылка на комментарий
Callisto, если структура таблиц не позволяет их менять (что имеет место быть в предложенном варианте от Gun12) то:

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Считаю что изначально нужно писать таблицы правильно, почему и не предложил вариант с перебором в каждом апдейте.

Не буду говорить о скоростях перебора и поиска по индексу в хэше, но эстетически выглядит подобный вариант, ИМХО, некрасиво.

Изменено пользователем Gun12
Ссылка на комментарий

Gun12, к сожалению в исходном вопросе нет условий по выбору структуры таблиц и порою приходится подстраиваться/использовать "как есть". Конечно же вариант предложенный тобою более оптимален, но если таблицы именно как в примерах вопроса - то это уже или неочевидно или даже неприменимо.

 

Примечание: Т.к. это все же топик в разделе "Школа ...", то упоминание о различных вариантах вполне уместно. ИМХО. Ну а выбор варианта - это уже и по контексту и по вкусу. ;-)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Можно и "по-буквоедствовать".

В этом случае вторая таблица вообще не нужна :)

function Update()
    local rnd = math.random( #table_1 )
    local txt = table_1[rnd]
    if rnd%3==1 then
        txt = txt.." "..table_3[math.random( #table_3 )]
    end
    return txt
end

 

 

Прошу прощения, за вмешательство прямо в пост, но что значит "вторая таблица вообще не нужна"?

ColR_iT

 

Добавлено через 9 мин.:

Я заметил последовательность 1,4,7,10 во второй таблице.

Это соответствует индексам их расположения в первой таблице.

Общее для них, это остаток от деления на 3. Т.е. единица.

1 тоже даёт остаток единицу.

Прикалываюсь короче. Но в данном случае работает ведь.

 

Да, действительно интересное решение. Здорово! Спасибо за разъяснение.

ColR_iT

Изменено пользователем ColR_iT
Ссылка на комментарий

Вот сейчас читаю и понимаю, что все-таки наверно неправильно сформулировала мысль. Хотя козалось вроде все грамотно излагаю :)

Вторая таблица как-раз очень нужна. Там только строковые значения, без индексов.

Вся схема это попытка реализовать динамические новости (АМК и OGSE) для программы Rainmeter. Все было готово, но, как всегда захотелось чуть-чуть усложнить схему (чтоб было еще рендомнее :) ).

 

Тут надо не вернуть строку, а сделать присвоение. Типа:

если Text_1 == table_2 тогда
    Text_2 = "1"

если Text_1 ~= table_2 тогда
    Text_2 = "2"

А далее Text_2 передается в другую таблицу, откуда уже получается конечный результат.

Вобщем должно быть как-то так, надеюсь сейчас лучше изложила.

Пока писала возникла одна идейка, пойду попробую.

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

userbar368.png

Ссылка на комментарий

Callisto, ну вот тепеть более понятны условия задачи/вопроса, в отличии от первоначальной формулировки:

Имеется три таблицы
, которая обычно трактуется как: "Дано: ... , требуется ..."

В уточненном случае конечно же структуру и наполнение таблиц следует подбирать по контексту задачи и, конечно же таблица со строками-ключами будет гораздо оптимальнее для использования.

И даже в значениях для ключей можно задавать функцию рандомного выбора из третьей таблицы ... Но это уже после собственно овладевания навыками работы с методами для таблиц. ;-)

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Что означает сей pattern? Где прочитать про составление pattern'ов(читал printf в C языках на википедии...не особо там понятно, или я тупой)

 

 "^%s*(.-)%s*$"

 

И что такое найденное вхождение?

Изменено пользователем ColR_iT
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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