# Random value from array? (Also: ™Bells+Whistles)

How do I make an array of values and then choose randomly from that array?

Next I'd like to add weights. In SC that would be Pwrand. Next I'd like to empty out all values before putting all values back in the array and then choosing randomly again. In sc that would be Pshuf. Next I'd like make sure there are no repeats of values ever. Not even when comparing the last value with the first value of a new shuffling. I don't know how to do that in SC.

edit retag close merge delete

( 2016-08-10 09:58:43 -0500 )edit

( 2016-11-14 08:32:48 -0500 )edit

Sort by » oldest newest most voted

Choose random array values:

choose ["a", "b", "c"]


With integer weights:

choose $concat$ zipWith replicate [1,2,3] ["a", "b", "c"]


With real weights is possible, but not as a one-liner. I think you'd need to take a cumulative sum of the weights and use rand to index, basically.

If I understand Pshuf correctly I think it's a little awkward in Haskell/Tidal. You can try a function like this:

let randperm t xs = pxs !! (floor $timeToRand t * (fromIntegral$ length pxs)) where pxs = permutations xs


so randperm 0 ["a", "b", "c"] will give you some random (but always the same if you use 0 as the first argument) permutation of the list. That'll be a list not a Pattern, but you could then use listToPat, preplace, etc...

I'm not sure what you mean by "no repeats of values ever". If there's only 3 things in the list, what happens after the 3rd is taken?

more

Oh yes, choose is great. I've used that.

d1 $s "rave2*8" # n (choose [1, 2, 3]) # cut "1"  Your solution here is great. Thank you so much. Very useful and superFunzees to mess around w/: d1$ s "rave2*8" # n (choose $concat$ zipWith replicate [1, 2, 3] [1, 2, 3]) # cut "1"


Much more elegant than my clunky workaround that I've been using up until now:

d1 $s "rave2*8" # n (choose [1, 2, 2, 3, 3, 3]) # cut "1"  Less chars and easy to read w/ that particular example but possibly infinitely more amount of chars and definitely harder to read with very large arrays. This bit went over my head. It looks cool though: let randperm t xs = pxs !! (floor$ timeToRand t * (fromIntegral \$ length pxs)) where pxs = permutations xs


I got it to evaluate ok and I can also run randperm 0 ["a", "b", "c"] ok. But that last bit about turning the list into a pattern I would love to be able to do on my own but sadly I lack the experience w/ Haskell.

I tried looking up mentions of listtoPat in Learn you a Haskell.

I found some mentions of it here: https://hackage.haskell.org/package/tidal-0.2/src/Pattern.hs

I dunno, could @bgold or someone else maybe help me out some more?

more

listToPat just turns a list into a basic pattern, which repeats each cycle and with each entry in the list taking up an equal part. So n (listToPat [1,2,3]) is exactly the same as n "1 2 3"

( 2016-11-15 07:27:22 -0500 )edit