serverless-spy
Version:
CDK-based library for writing elegant integration tests on AWS serverless architecture and an additional web console to monitor events in real time.
97 lines (73 loc) • 1.95 kB
JavaScript
/**
* Obliterator Permutations Function
* ==================================
*
* Iterator returning permutations of the given array.
*/
var Iterator = require('./iterator.js');
/**
* Helper mapping indices to items.
*/
function indicesToItems(target, items, indices, r) {
for (var i = 0; i < r; i++)
target[i] = items[indices[i]];
}
/**
* Permutations.
*
* @param {array} array - Target array.
* @param {number} r - Size of the subsequences.
* @return {Iterator}
*/
module.exports = function permutations(array, r) {
if (!Array.isArray(array))
throw new Error('obliterator/permutations: first argument should be an array.');
var n = array.length;
if (arguments.length < 2)
r = n;
if (typeof r !== 'number')
throw new Error('obliterator/permutations: second argument should be omitted or a number.');
if (r > n)
throw new Error('obliterator/permutations: the size of the subsequences should not exceed the length of the array.');
var indices = new Uint32Array(n),
subsequence = new Array(r),
cycles = new Uint32Array(r),
first = true,
i;
for (i = 0; i < n; i++) {
indices[i] = i;
if (i < r)
cycles[i] = n - i;
}
i = r;
return new Iterator(function next() {
if (first) {
first = false;
indicesToItems(subsequence, array, indices, r);
return {value: subsequence};
}
var tmp,
j;
i--;
if (i < 0)
return {done: true};
cycles[i]--;
if (cycles[i] === 0) {
tmp = indices[i];
for (j = i; j < n - 1; j++)
indices[j] = indices[j + 1];
indices[n - 1] = tmp;
cycles[i] = n - i;
return next();
}
else {
j = cycles[i];
tmp = indices[i];
indices[i] = indices[n - j];
indices[n - j] = tmp;
i = r;
indicesToItems(subsequence, array, indices, r);
return {value: subsequence};
}
});
};