From cb7612aef69fdf8839972cce4357cc1b9cb106e8 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 6 Feb 2017 23:53:17 -0800 Subject: [PATCH] Simplify `shuffle` and `sample`. --- .internal/arraySample.js | 15 --------------- .internal/arraySampleSize.js | 17 ----------------- .internal/arrayShuffle.js | 15 --------------- .internal/baseRandom.js | 14 -------------- .internal/baseSample.js | 15 --------------- .internal/baseSampleSize.js | 18 ------------------ .internal/baseShuffle.js | 15 --------------- .internal/shuffleSelf.js | 28 ---------------------------- sample.js | 15 ++++++--------- sampleSize.js | 29 ++++++++++++++++++++--------- shuffle.js | 25 ++++++++++++++++++------- 11 files changed, 44 insertions(+), 162 deletions(-) delete mode 100644 .internal/arraySample.js delete mode 100644 .internal/arraySampleSize.js delete mode 100644 .internal/arrayShuffle.js delete mode 100644 .internal/baseRandom.js delete mode 100644 .internal/baseSample.js delete mode 100644 .internal/baseSampleSize.js delete mode 100644 .internal/baseShuffle.js delete mode 100644 .internal/shuffleSelf.js diff --git a/.internal/arraySample.js b/.internal/arraySample.js deleted file mode 100644 index d2b983e79..000000000 --- a/.internal/arraySample.js +++ /dev/null @@ -1,15 +0,0 @@ -import baseRandom from './baseRandom.js' - -/** - * A specialized version of `sample` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @returns {*} Returns the random element. - */ -function arraySample(array) { - const length = array.length - return length ? array[baseRandom(0, length - 1)] : undefined -} - -export default arraySample diff --git a/.internal/arraySampleSize.js b/.internal/arraySampleSize.js deleted file mode 100644 index d33052de8..000000000 --- a/.internal/arraySampleSize.js +++ /dev/null @@ -1,17 +0,0 @@ -import baseClamp from './baseClamp.js' -import copyArray from './copyArray.js' -import shuffleSelf from './shuffleSelf.js' - -/** - * A specialized version of `sampleSize` for arrays. - * - * @private - * @param {Array} array The array to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ -function arraySampleSize(array, n) { - return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)) -} - -export default arraySampleSize diff --git a/.internal/arrayShuffle.js b/.internal/arrayShuffle.js deleted file mode 100644 index 5792e1043..000000000 --- a/.internal/arrayShuffle.js +++ /dev/null @@ -1,15 +0,0 @@ -import copyArray from './copyArray.js' -import shuffleSelf from './shuffleSelf.js' - -/** - * A specialized version of `shuffle` for arrays. - * - * @private - * @param {Array} array The array to shuffle. - * @returns {Array} Returns the new shuffled array. - */ -function arrayShuffle(array) { - return shuffleSelf(copyArray(array)) -} - -export default arrayShuffle diff --git a/.internal/baseRandom.js b/.internal/baseRandom.js deleted file mode 100644 index c04fc620d..000000000 --- a/.internal/baseRandom.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * 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 + Math.floor(Math.random() * (upper - lower + 1)) -} - -export default baseRandom diff --git a/.internal/baseSample.js b/.internal/baseSample.js deleted file mode 100644 index de50cae0a..000000000 --- a/.internal/baseSample.js +++ /dev/null @@ -1,15 +0,0 @@ -import arraySample from './arraySample.js' -import values from '../values.js' - -/** - * The base implementation of `sample`. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - */ -function baseSample(collection) { - return arraySample(values(collection)) -} - -export default baseSample diff --git a/.internal/baseSampleSize.js b/.internal/baseSampleSize.js deleted file mode 100644 index 9c10b684c..000000000 --- a/.internal/baseSampleSize.js +++ /dev/null @@ -1,18 +0,0 @@ -import baseClamp from './baseClamp.js' -import shuffleSelf from './shuffleSelf.js' -import values from '../values.js' - -/** - * The base implementation of `sampleSize` without param guards. - * - * @private - * @param {Array|Object} collection The collection to sample. - * @param {number} n The number of elements to sample. - * @returns {Array} Returns the random elements. - */ -function baseSampleSize(collection, n) { - const array = values(collection) - return shuffleSelf(array, baseClamp(n, 0, array.length)) -} - -export default baseSampleSize diff --git a/.internal/baseShuffle.js b/.internal/baseShuffle.js deleted file mode 100644 index f497405f7..000000000 --- a/.internal/baseShuffle.js +++ /dev/null @@ -1,15 +0,0 @@ -import shuffleSelf from './shuffleSelf.js' -import values from '../values.js' - -/** - * The base implementation of `shuffle`. - * - * @private - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - */ -function baseShuffle(collection) { - return shuffleSelf(values(collection)) -} - -export default baseShuffle diff --git a/.internal/shuffleSelf.js b/.internal/shuffleSelf.js deleted file mode 100644 index 4ca1701f7..000000000 --- a/.internal/shuffleSelf.js +++ /dev/null @@ -1,28 +0,0 @@ -import baseRandom from './baseRandom.js' - -/** - * A specialized version of `shuffle` which mutates and sets the size of `array`. - * - * @private - * @param {Array} array The array to shuffle. - * @param {number} [size=array.length] The size of `array`. - * @returns {Array} Returns `array`. - */ -function shuffleSelf(array, size) { - let index = -1 - const length = array.length - const lastIndex = length - 1 - - size = size === undefined ? length : size - while (++index < size) { - const rand = baseRandom(index, lastIndex) - const value = array[rand] - - array[rand] = array[index] - array[index] = value - } - array.length = size - return array -} - -export default shuffleSelf diff --git a/sample.js b/sample.js index 0e3b6e6c0..60e2d8921 100644 --- a/sample.js +++ b/sample.js @@ -1,21 +1,18 @@ -import arraySample from './.internal/arraySample.js' -import baseSample from './.internal/baseSample.js' - /** - * Gets a random element from `collection`. + * Gets a random element from `array`. * * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. + * @category Array + * @param {Array} array The array to sample. * @returns {*} Returns the random element. * @example * * sample([1, 2, 3, 4]) * // => 2 */ -function sample(collection) { - const func = Array.isArray(collection) ? arraySample : baseSample - return func(collection) +function sample(array) { + const length = array == null ? 0 : array.length + return length ? array[Math.floor(Math.random() * length)] : undefined } export default sample diff --git a/sampleSize.js b/sampleSize.js index f92badb96..5488f9835 100644 --- a/sampleSize.js +++ b/sampleSize.js @@ -1,15 +1,13 @@ -import arraySampleSize from './.internal/arraySampleSize.js' -import baseSampleSize from './.internal/baseSampleSize.js' import isIterateeCall from './.internal/isIterateeCall.js' import toInteger from './toInteger.js' /** - * Gets `n` random elements at unique keys from `collection` up to the - * size of `collection`. + * Gets `n` random elements at unique keys from `array` up to the + * size of `array`. * * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. + * @category Array + * @param {Array} array The array to sample. * @param {number} [n=1] The number of elements to sample. * @param- {Object} [guard] Enables use as an iteratee for methods like `map`. * @returns {Array} Returns the random elements. @@ -21,14 +19,27 @@ import toInteger from './toInteger.js' * sampleSize([1, 2, 3], 4) * // => [2, 3, 1] */ -function sampleSize(collection, n, guard) { +function sampleSize(array, n, guard) { if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { n = 1 } else { n = toInteger(n) } - const func = Array.isArray(collection) ? arraySampleSize : baseSampleSize - return func(collection, n) + const length = array == null ? 0 : array.length + if (!length || n < 1) { + return [] + } + n = n > length ? length : n + let index = -1 + const lastIndex = n - 1 + const result = copyArray(array) + while (++index < n) { + const rand = index + Math.floor(Math.random() * (lastIndex - index + 1)) + const value = result[rand] + result[rand] = result[index] + result[index] = value + } + return result } export default sampleSize diff --git a/shuffle.js b/shuffle.js index ad5f627c8..aa18d8706 100644 --- a/shuffle.js +++ b/shuffle.js @@ -1,22 +1,33 @@ -import arrayShuffle from './.internal/arrayShuffle.js' -import baseShuffle from './.internal/baseShuffle.js' +import copyArray from './copyArray.js' /** * Creates an array of shuffled values, using a version of the * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to shuffle. + * @category Array + * @param {Array} array The array to shuffle. * @returns {Array} Returns the new shuffled array. * @example * * shuffle([1, 2, 3, 4]) * // => [4, 1, 3, 2] */ -function shuffle(collection) { - const func = Array.isArray(collection) ? arrayShuffle : baseShuffle - return func(collection) +function shuffle(array) { + const length = array == null ? 0 : array.length + if (!length) { + return [] + } + let index = -1 + const lastIndex = length - 1 + const result = copyArray(array) + while (++index < length) { + const rand = index + Math.floor(Math.random() * (lastIndex - index + 1)) + const value = result[rand] + result[rand] = result[index] + result[index] = value + } + return result } export default shuffle