Page 1 of 1

### need a random value from table

Posted: Sun May 28, 2017 10:19 pm
Hi,
lest's say I have a table (not a list):
Code: Select all
t={[0]=0,[10]=10,[20]=20,[30]=30}

and I'd like to get some random value from it.
So far I'm using following code:
Code: Select all
Local rand=Rnd(TableItems(t))
Local b   = -1
For i,v In Pairs(t)
b = b + 1
If b = rand
DebugPrint(t[i])
Break
EndIf
Next

Is there a faster way to get it done?

Thanks

### Re: need a random value from table

Posted: Mon May 29, 2017 3:27 pm
Yes there is, depending how your code works.

You have a table:
Code: Select all
table = {
["item1"] = 10,
["item2"] = 5,
["item3"] = 20,
...
}

But question is, is the amount of "itemx" the same, or does it keep changing during the program too?

Suppose it is stable, then you can have two different tables that keep track of same thing:

Code: Select all
Table = {like above}
Helptable = { "item1", "item2", "item3"}

Now you can do following:
Code: Select all
Rand = Rnd( TableItems(helptable) )
key = helptable[Rand]
debugprint( Table[key] )

and you are getting the value you are after.

If amount of "itemx" keep changing, then you need to remember to update that helptable as well. Good thing however is that if you are looking for random value among all the "item"s, then you dont need to worry that table and helptable have them in same order, as it doesnt really matter which "itemx" it happens to pick as long as it is random and exists. And do remember, if you remove one "itemx" from your table, you need to remove that from helptable as well, or you might be trying to access non existing table item.

### Re: need a random value from table

Posted: Mon May 29, 2017 9:39 pm
Thanks for the idea.
That table is changing - it is getting smaller and smaller until it becomes null.

I asked that question because I'm trying to speed up my program as much as possible on classic amiga (that "get random" routine is used in main loop of the script).
I am going to try your solution and will report if that speeds up things

Thanks

### Re: need a random value from table

Posted: Tue May 30, 2017 2:54 pm
Hi

I think you may be able to simplify the process even further without a help table by using RemoveItem() like this...

mytbl = {10, 5, 20}

Function GetRndValue()
Local response
rand=Rnd(TableItems(mytbl))
response=mytbl[rand]
RemoveItem(mytbl,rand)
Return(response)
EndFunction

Now each call to the function will pick a value using a random value among the existing indexes (which implicitly goes between 0 and the number of items-1). Then remove that item with RemoveItem() and you will have a 'rebuilt' and reduced table since Hollywood automatically handles the indexing with implicitly assigned indexes.

Of course you will eventually run out of items in the list as you remove them. So you have to be able to handle this condition in your code.

regards
Jesper

### Re: need a random value from table

Posted: Tue May 30, 2017 3:38 pm
I think that is not going to work in my case:
Code: Select all
mytbl={ [0]="zero" , [1]="one" , [6]="six" }

following line will give me a number between 0 and 2
Code: Select all
rand=Rnd(TableItems(mytbl))

but position no.2 does not exist thus this
Code: Select all
response=mytbl[rand]

will throw an error if RAND=2

### Re: need a random value from table

Posted: Tue May 30, 2017 11:24 pm
I don't think there's a faster way than your original code based on iterating the table until you reach the random index. There's no way to go from an absolute, consecutive index to a non-consecutive index without iterating through the table.

### Re: need a random value from table

Posted: Wed May 31, 2017 2:24 pm
Hi

The procedure I suggest will work provided the value you are interested in is the content (which might be a number or a string) and not its index in an table. As I understand your task, you have a list of values
and wish to grab a random item in the list for some purpose, then reduce the list by removing that item, then later grab another random item, then reduce the list by removing that item... etc.

In other words, in your situation the actual value of the index in the table is not important, which is why you can use the implicit indexing (consecutive indexes). Because it is only used to do random picking among the items. If however you actually use the index value as a parameter in some other context, then my idea is not useful.

regards
Jesper