Выберите случайный предмет из таблицы
Моя цель - выбрать случайный предмет из таблицы в Lua.
Это то, что я получил до сих пор, но в настоящее время это не работает:
local myTable = { 'a', 'b', 'c', 'd' }
print( myTable[ math.random( 0, #myTable - 1 ) ] )
Как я могу исправить приведенный выше код, чтобы он работал как задумано? (Или какой другой метод я мог бы использовать?)
Ответы
Ответ 1
Lua индексирует таблицы от 1, в отличие от C, Java и т.д., которые индексируют массивы из 0. Это означает, что в вашей таблице действительными индексами являются: 1, 2, 3, 4. То, что вы ищете, следующее
print( myTable[ math.random( #myTable ) ] )
При вызове с одним аргументом math.random(n)
возвращает случайное целое число от 1 до n
, включая.
Ответ 2
Я думаю, что этот вопрос также нуждается в более общем ответе. Нет никаких ограничений на создание таблиц lua с последовательностью целых чисел, начиная с 1. Ключи могут быть действительно любыми - они могут быть даже другими таблицами lua! В таких случаях такие функции, как #myTable, могут дать ответ, которого вы не ожидаете (при использовании без каких-либо настраиваемых метаданных). Единственный надежный способ получить все ключи в таблице - перебрать его:
-- iterate over whole table to get all keys
local keyset = {}
for k in pairs(myTable) do
table.insert(keyset, k)
end
-- now you can reliably return a random key
random_elem = myTable[keyset[math.random(#keyset)]]
Я также добавлю, что оригинальное решение Michal Kottman будет работать отлично, если все ваши ключи представляют собой последовательность чисел, начиная с 1. Это происходит, когда вы создаете таблицу как myTable = {'a','b','c'}
. Поэтому для ситуаций, когда таблицы создаются таким образом, получение случайных элементов из таблицы будет быстрее.
Ответ 3
Тест:
t = {'a', 'b', 'c'}
print(t[0])
дает nil
. На самом деле 0 выходит за пределы (попробуйте t[20]
)... поэтому случайное значение должно быть от 1 до #myTable
(включительно), потому что первый элемент таблицы помечен (проиндексирован) как 1, если вы пишете только exp
, см. конструктор таблицы ("Наконец, поля формы exp эквивалентны [i] = exp, где i - последовательные целые числа, начинающиеся с 1.").
Если вы передадите math.random просто аргумент n
, вы получите случайное число от 1 до n
включительно. Это исправляет ваш пример:
print(myTable[math.random(#myTable)])
Ответ 4
Я лично использую следующую функцию, вдохновленную @ahmadh
function random_elem(tb)
local keys = {}
for k in pairs(tb) do table.insert(tb, k) end
return tb[keys[math.random(#keys)]]
end