Random

JavaScript

"use strict";
var rand = Math.random;

/**
 * Return a random floating point number N such that
 * a <= N <= b for a <= b and b <= N <= a for b < a
 */
rand.uniform = function(a, b) {
    return rand() * (b - a) + a;
};

/**
 * Functions for integers:
 * =======================
 */

/**
 * Return a random integer N such that a <= N < b.
 */
rand.int_ = function(a, b) {
    return Math.floor(rand.uniform(a, b));
};

/**
 * Return a randomly selected element from range(start, stop, step).
 * This is equivalent to choice(range(start, stop, step)), but doesn’t
 * actually build a range object.
 * 
 * The positional argument pattern matches that of range(). Keyword
 * arguments should not be used because the function may use them in
 * unexpected ways.
 */
rand.range = function(start, stop, step) {
    switch (arguments.length) {
    case 1:
        return rand.int_(0, start);
    case 2:
        return rand.int_(start, stop);
    case 3:
        return rand.int_(start, stop / step) * step;
    default:
        return 0;
    }
};

/**
 * Return a random integer N such that a <= N <= b.
 * Alias for `rand.range(a, b+1)`.
 */
rand.int = function(a, b) {
    return rand.int_(a, b + 1);
};

/**
 * Functions for arrays and sequences:
 * ===================================
 */

/**
 *
 */
rand.index = function(ary) {
    return rand.int_(0, ary.length);
};

/**
 *
 */
rand.item = function(ary) {
    return ary[rand.index(ary)];
};

/**
 * Functions for objects:
 * ======================
 */

/**
 *
 */
rand.key_ = function(obj) {
    var k, r, i = 0;
    for (k in obj) {
        if (obj.hasOwnProperty(k) && Math.random() < 1 / ++i) {
            r = k;
        }
    }
    return r;
};

/**
 *
 */
rand.key = function(obj) {
    if (!Object.keys) { return rand.key_(obj); }
    return Math.random.item(Object.keys(obj));
};

/**
 *
 */
rand.choice = function(obj) {
    return obj[rand.key(obj)];
};