Подтвердить что ты не робот

Выберите случайный предмет из таблицы

Моя цель - выбрать случайный предмет из таблицы в Lua.

Это то, что я получил до сих пор, но в настоящее время это не работает:

local myTable = { 'a', 'b', 'c', 'd' }
print( myTable[ math.random( 0, #myTable - 1 ) ] )

Как я могу исправить приведенный выше код, чтобы он работал как задумано? (Или какой другой метод я мог бы использовать?)

4b9b3361

Ответ 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