Stupid Groovy Tricks

Date August 27, 2008

Someone recently asked how to get a random element from an array.  In PHP it’s pretty straightforward - array_rand($x) - but there’s not (AFAICT) a built-in way in Groovy to do this.  So I wrote a little something which should hopefully demonstrate the power of the metaClass stuff to boot.

ArrayList.metaClass.getRand = { number ->
 if(number==0) {
   return delegate[new Random().nextInt(delegate.size)]
 } else {
   def tempList = []
   def counter = 0
   while(counter>number) {
     tempList.add(delegate[new Random().nextInt(delegate.size)])
     counter++
   }
   return tempList
 }
}
def names = ['mike','matt','mark','lesley','jean','ron','jeff','martine']
println names.getRand()
println names.getRand(5)

The first call to getRand() on the names list will just return one name from the list.  The second will return 5 random entries (and some could theoretically be repeated).  I’ve added this getRand() method to the base ArrayList class at runtime, even though it’s likely declared ‘final’ in Java’s base libraries.  This is one of the core powers of Groovy, and is pretty slick, imo.

 Did you like this post? Buy me a hot chocolate!

3 Responses to “Stupid Groovy Tricks”

  1. mgkimsal said:

    BTW, this was a first pass. If there’s any way of making this groovier, let me know!

  2. Bob said:

    Consider the following if you want to prevent duplicates in the else branch. It will be slower in general since it will shuffle the entire list.

    def tempList= new ArrayList(delegate)
    Collections.shuffle(tempList)
    tempList.subList(0, length)
    return tempList

    This might useful if you a supply a third boolean argument to the closure that indicates whether duplicates should be allowed or not.

    Nice post!

  3. Bob said:

    That should be

    return tempList.subList(0, length)

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="">