Выберите случайный предмет из таблицы - PullRequest
29 голосов
/ 07 июня 2010

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

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

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

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

Ответы [ 4 ]

61 голосов
/ 07 июня 2010

Lua индексирует таблицы из 1, в отличие от C, Java и т. Д., Который индексирует массивы из 0. Это означает, что в вашей таблице допустимые индексы: 1, 2, 3, 4. То, что вы ищете, это следующее:

print( myTable[ math.random( #myTable ) ] )

При вызове с одним аргументом math.random(n) возвращает случайное целое число от 1 до n, включая.

11 голосов
/ 26 мая 2016

Я думаю, что вопрос также нуждается в более общем ответе. Не существует ограничений на создание таблиц 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'}. Так что в ситуациях, когда таблицы построены таким образом, получение случайных элементов из таблицы будет быстрее.

1 голос
/ 07 июня 2010

Тест:

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)])
0 голосов
/ 30 октября 2018

Я лично использую следующую функцию, вдохновленную @ 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
...