Snippets (Ledger)

Function returns randomised (shuffled) number range in a table:


Used in New Tool: (3.1) Random Plug (Feb 2019) to return a random plugin from the table of available plugs in renoise.

function returns a table of unique,random,consecutive numbers from 1 to (max)<- settable

i.e.
local random_tab = get_table_of_random_numbers(10)

random_tab[1] → 7
random_tab[2] → 4
random_tab[3] → 10
random_tab[4] → 6
random_tab[5] → 3
random_tab[6] → 2
random_tab[7] → 5
random_tab[8] → 9
random_tab[9] → 8
random_tab[10] → 1


click for code

--function returns a table of unique,random,consecutive numbers from 1 to (max)<- settable
-------------------------------------------------------------------------------------------
--i.e. you have a list of 7 meals that you want to cook in random order over 7 days. 
--Each meal must be chosen once with no repeats:

--/////////////////////////////////////////
--call the function
--local random_meal_indexes = get_table_of_random_numbers(7)

--loop to use the 7 new random indexes
--for i = 1,7 do
--  local meal_idx = random_meal_indexes[i]
--  print all_meals[meal_idx]
--end
--//////////////////////////////////////////

--------------------------------------
function get_table_of_random_numbers(max)
--------------------------------------
  
  --outer scope table
  local g_index_store = {}
  ------------------------------------------------------------------
  local function get_random_index(max)
  ------------------------------------------------------------------
    --g_index_store will have consecutive entries { [1] = 1, [2] = 2, [3] = 3, [4] = 4, etc..} up to (max)
    --We choose a random index using Luas math.random(), with limit set to size of #g_index_store.
    --Once we have used an entry e.g entry [3] we discard it using lua's table.remove() function. e.g. when 3 has been removed the items become
    --{ [1] = 1, [2] = 2, [3] = 4, [4] = 5, etc..}
    --The value for 3 has now become 4 and the value for 4 has become 5.  g_index_store is now one entry shorter.
    
    --when max is too small fire error
    if max < 2 then
      error("max must be greater than 1")
      return
    end
    
    --if index table has been emptied or it is the first run re-populate it
    if #g_index_store == 0 then
      for i = 1,max do
        --a simple table where { [1] = 1, [2] = 2, [3] = 3 etc..}
        g_index_store[i] = i
      end
    end
      
    --random number
    ---------------
    --get os.time() as a seed
    local t = os.time()
    --as os.time() updates slowly we multiply it by random number before passing to randomseed
    math.randomseed((t * math.random(1,789)))
    --get random number based on os.time()
    local ran_num = nil
    --random number between 1 and the length of the index-storing table
    ran_num = math.random(1, #g_index_store)
    
    --get new random index number from the global g_index_store table
    ---------------------------------------------------------------
    local rand_index = g_index_store[ran_num]
    --discard index value/ entry so the used 'index value' can not be selected again.
    table.remove(g_index_store ,ran_num) 
    --return the current index value
    return rand_index
  end
  ----end local function
  
  --to store random numbers
  local random_table = {}
  for i = 1,max do
    random_table[i] = get_random_index(max)
  end
  --return completed table which can be cross-indexed for random indexes in a separate table/list
  return random_table
end

--run and print
print("\n")
rprint(get_table_of_random_numbers(7))