From 01b123b9f850bbcb17760559afc7bfeb89adc81a Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 4 Jun 2003 00:03:58 +0000 Subject: [PATCH] Added some utility methods for selecting a random element from an array or iteration of known size. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2634 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- src/java/com/threerings/util/RandomUtil.java | 98 +++++++++++++++++++- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/src/java/com/threerings/util/RandomUtil.java b/src/java/com/threerings/util/RandomUtil.java index dab85663a..6768112bf 100644 --- a/src/java/com/threerings/util/RandomUtil.java +++ b/src/java/com/threerings/util/RandomUtil.java @@ -1,12 +1,13 @@ // -// $Id: RandomUtil.java,v 1.8 2003/05/16 02:21:37 ray Exp $ +// $Id: RandomUtil.java,v 1.9 2003/06/04 00:03:58 mdb Exp $ package com.threerings.util; -import com.samskivert.util.IntListUtil; - +import java.util.Iterator; import java.util.Random; +import com.samskivert.util.IntListUtil; + /** * Provides miscellaneous utility routines to simplify obtaining * useful random number values and to centralize seeding and proper @@ -80,4 +81,95 @@ public class RandomUtil Log.logStackTrace(new Throwable()); return 0; } + + /** + * Picks a random object from the supplied array of values. Even + * weight is given to all elements of the array. + * + * @return a randomly selected item or null if the array is null or of + * length zero. + */ + public static Object pickRandom (Object[] values) + { + return (values == null || values.length == 0) ? null : + values[getInt(values.length)]; + } + + /** + * Picks a random object from the supplied array of values, not + * including the specified skip object as a possible selection + * (equality with the skipped object is referential rather than via + * {@link Object#equals}). The element to be skipped must exist in the + * array exactly once. Even weight is given to all elements of the + * array except the skipped element. + * + * @return a randomly selected item or null if the array is null, of + * length zero or contains only the skip item. + */ + public static Object pickRandom (Object[] values, Object skip) + { + if (values == null || values.length < 2) { + return null; + } + int index = getInt(values.length-1); + for (int ii = 0; ii <= index; ii++) { + if (values[ii] == skip) { + index++; + } + } + return (index >= values.length) ? null : values[index]; + } + + /** + * Picks a random object from the supplied iterator (which must + * iterate over exactly count objects. + * + * @return a randomly selected item. + * + * @exception NoSuchElementException thrown if the iterator provides + * fewer than count elements. + */ + public static Object pickRandom (Iterator iter, int count) + { + if (count < 1) { + throw new IllegalArgumentException( + "Must have at least one element [count=" + count + "]"); + } + + Object value = iter.next(); + for (int ii = 0, ll = getInt(count); ii < ll; ii++) { + value = iter.next(); + } + return value; + } + + /** + * Picks a random object from the supplied iterator (which must + * iterate over exactly count objects. The specified skip + * object will be skipped when selecting a random value. The skipped + * object must exist exactly once in the set of objects returned by + * the iterator. + * + * @return a randomly selected item. + * + * @exception NoSuchElementException thrown if the iterator provides + * fewer than count elements. + */ + public static Object pickRandom (Iterator iter, int count, Object skip) + { + if (count < 2) { + throw new IllegalArgumentException( + "Must have at least two elements [count=" + count + "]"); + } + + int index = getInt(count-1); + Object value = null; + do { + value = iter.next(); + if (value == skip) { + value = iter.next(); + } + } while (index-- > 0); + return value; + } }