From 56d7ccbce18164706447c2c67c2e87b3d0016462 Mon Sep 17 00:00:00 2001 From: "Matt R. Wilson" Date: Sat, 10 Mar 2018 21:13:22 -0700 Subject: Bugfix random.shuffle last element. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a bug in the implementation of the modern Fisher–Yates algorithm in that `i` was being decremented prematurely in each loop. This caused the last element of the array to never be swapped and therefore remain the last element. Updated doc to denote the provided array is shuffled in place. --- lib/helpers.js | 13 ++++++++++--- test/helpers.unit.js | 13 +++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/helpers.js b/lib/helpers.js index 9bb78267..62a8bfa9 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -191,17 +191,24 @@ var Helpers = function (faker) { }; /** - * takes an array and returns it randomized + * takes an array and randomizes it in place then returns it + * + * uses the modern version of the Fisher–Yates algorithm * * @method faker.helpers.shuffle * @param {array} o */ self.shuffle = function (o) { if (typeof o === 'undefined' || o.length === 0) { - return []; + return o || []; } o = o || ["a", "b", "c"]; - for (var j, x, i = o.length-1; i; j = faker.random.number(i), x = o[--i], o[i] = o[j], o[j] = x); + for (var x, j, i = o.length - 1; i > 0; --i) { + j = faker.random.number(i); + x = o[i]; + o[i] = o[j]; + o[j] = x; + } return o; }; diff --git a/test/helpers.unit.js b/test/helpers.unit.js index b9d559dd..058b8de0 100644 --- a/test/helpers.unit.js +++ b/test/helpers.unit.js @@ -43,6 +43,19 @@ describe("helpers.js", function () { var shuffled = faker.helpers.shuffle([]); assert.ok(shuffled.length === 0); }); + + it("mutates the input array in place", function () { + var input = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; + var shuffled = faker.helpers.shuffle(input); + assert.deepEqual(shuffled, input); + }); + + it("all items shuffled as expected when seeded", function () { + var input = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; + faker.seed(100); + var shuffled = faker.helpers.shuffle(input); + assert.deepEqual(shuffled, ["b", "e", "a", "d", "j", "i", "h", "c", "g", "f"]); + }); }); describe("slugify()", function () { -- cgit v1.2.3