Array shuffle

10 views
Skip to first unread message

Albert Shih

unread,
Jun 10, 2020, 7:12:56 AM6/10/20
to puppet...@googlegroups.com
Hi everyone

I try to do a very simple shuffle in a array but I need the shuffle to by
repeatable like fqdn_rand.

In any other langage it's seem very simple to do a Fischer-Yate but only
with map/reduce like I cannot figure out how to do that.

Regards.

--
Albert SHIH
Observatoire de Paris
Heure local/Local time:
Wed 10 Jun 2020 01:07:12 PM CEST

Henrik Lindberg

unread,
Jun 11, 2020, 3:45:51 PM6/11/20
to puppet...@googlegroups.com

There are a couple of ways to achieve this.

You can write a shuffle function in Ruby, take a copy of the input array
and return a shuffled copy using Fischer-Yate algorithm.

Or write in Puppet using random numbers and sorting.

Create an array of equal length of the original, containing tuples of
value and a *unique* random number. This array is then sorted on the
random value. Here as how that can be done:


function shuffle($original) {
generate_unique_random(size($original))
.map() |$i, $random | { [$random, $original[$i]] }
.sort() |$a, $b| { compare($a[0], $b[0])}
.map() |$pair| { $pair[1] }
}

['blue', 'red', 'green'].shuffle.notice()


Now you need to write the unique random function. This is a bit
difficult in puppet as there is no unbound iteration (worst case you
could have a very long series of exactly the same value). What you can
do however is generate more values (with a wide spread), unique them and
then slice them to the desires size. Here I multiply by 3 and spread
result over 100000.

function generate_unique_random($size) {
($size * 3).map |$seed| {
fqdn_rand(100000 * $size, $seed)}
.unique()[0, $size]
}

Output from the above:

Notice: Scope(Class[main]): [red, blue, green]

The shuffle is stable per node (you always get the same result).

Hope that helps
- henrik
--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Reply all
Reply to author
Forward
0 new messages