/** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ var keys = require('lodash.keys'); /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** `Object#toString` result references. */ var funcTag = '[object Function]', genTag = '[object GeneratorFunction]'; /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** * The base implementation of `_.values` and `_.valuesIn` which creates an * array of `object` property values corresponding to the property names * of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the array of property values. */ function baseValues(object, props) { return arrayMap(props, function(key) { return object[key]; }); } /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeFloor = Math.floor, nativeRandom = Math.random; /** * The base implementation of `_.property` without support for deep paths. * * @private * @param {string} key The key of the property to get. * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; } /** * The base implementation of `_.random` without support for returning * floating-point numbers. * * @private * @param {number} lower The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the random number. */ function baseRandom(lower, upper) { return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); } /** * Gets the "length" property value of `object`. * * **Note:** This function is used to avoid a * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects * Safari on at least iOS 8.1-8.3 ARM64. * * @private * @param {Object} object The object to query. * @returns {*} Returns the "length" value. */ var getLength = baseProperty('length'); /** * Gets a random element from `collection`. * * @static * @memberOf _ * @since 2.0.0 * @category Collection * @param {Array|Object} collection The collection to sample. * @returns {*} Returns the random element. * @example * * _.sample([1, 2, 3, 4]); * // => 2 */ function sample(collection) { var array = isArrayLike(collection) ? collection : values(collection), length = array.length; return length > 0 ? array[baseRandom(0, length - 1)] : undefined; } /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(getLength(value)) && !isFunction(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, * else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 8 which returns 'object' for typed array and weak map constructors, // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. var tag = isObject(value) ? objectToString.call(value) : ''; return tag == funcTag || tag == genTag; } /** * Checks if `value` is a valid array-like length. * * **Note:** This function is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, * else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Creates an array of the own enumerable string keyed property values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.values(new Foo); * // => [1, 2] (iteration order is not guaranteed) * * _.values('hi'); * // => ['h', 'i'] */ function values(object) { return object ? baseValues(object, keys(object)) : []; } module.exports = sample;