Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes issue #288: Function hangs when selecting huge number of keys f…
…rom huge array
- Loading branch information
Showing
1 changed file
with
25 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,32 @@ | ||
module.exports = function array_rand (input, numReq) { // eslint-disable-line camelcase | ||
// discuss at: http://locutus.io/php/array_rand/ | ||
// original by: Waldo Malqui Silva (http://waldo.malqui.info) | ||
// example 1: array_rand( ['Kevin'], 1 ) | ||
// returns 1: 0 | ||
// discuss at: http://locutus.io/php/array_rand/ | ||
// original by: Waldo Malqui Silva (http://waldo.malqui.info) | ||
// reimplemented by: Rafał Kukawski | ||
// example 1: array_rand( ['Kevin'], 1 ) | ||
// returns 1: 0 | ||
|
||
var indexes = [] | ||
var ticks = numReq || 1 | ||
var checkDuplicate = function (input, value) { | ||
var exist = false | ||
var index = 0 | ||
var il = input.length | ||
while (index < il) { | ||
if (input[index] === value) { | ||
exist = true | ||
break | ||
} | ||
index++ | ||
} | ||
return exist | ||
} | ||
// By using Object.keys we support both, arrays and objects | ||
// which phpjs wants to support | ||
var keys = Object.keys(array); | ||
|
||
if (Object.prototype.toString.call(input) === '[object Array]' && ticks <= input.length) { | ||
while (true) { | ||
var rand = Math.floor((Math.random() * input.length)) | ||
if (indexes.length === ticks) { | ||
break | ||
} | ||
if (!checkDuplicate(indexes, rand)) { | ||
indexes.push(rand) | ||
} | ||
} | ||
if (typeof num === 'undefined' || num === null) { | ||
num = 1; | ||
} else { | ||
indexes = null | ||
num = +num; | ||
} | ||
|
||
if (isNaN(num) || num < 1 || num > keys.length) { | ||
return null; | ||
} | ||
|
||
// shuffle the array of keys | ||
for (var i = keys.length - 1; i > 0; i--) { | ||
var j = Math.floor(Math.random() * (i + 1)); // 0 ≤ j ≤ i | ||
|
||
var tmp = keys[j]; | ||
keys[j] = keys[i]; | ||
keys[i] = tmp; | ||
} | ||
|
||
return ((ticks === 1) ? indexes[0] : indexes) | ||
return num === 1 ? keys[0] : keys.slice(0, num); | ||
} |