115 lines
2.7 KiB
JavaScript
115 lines
2.7 KiB
JavaScript
/**
|
|
* Represents a set that is randomized each time the first element is reached.
|
|
* The set will loop back to the first element until the required number of
|
|
* samples are satisfied.
|
|
*
|
|
* Note that this means that, should the sample size be larger than the number
|
|
* of elements in the set, the set will be randomized only for each iteration,
|
|
* which may not be what you want for a truely random sample set.
|
|
*/
|
|
rectest.set.RandomGroupedSet = Class( 'RandomGroupedSet' )
|
|
.implement( rectest.set.Set )
|
|
.extend(
|
|
{
|
|
/**
|
|
* Number of samples remaining
|
|
* @var {number}
|
|
*/
|
|
'private _samplesRemain': 0,
|
|
|
|
/**
|
|
* Set to operate on
|
|
* @var {Array.<string>}
|
|
*/
|
|
'private _set': [],
|
|
|
|
/**
|
|
* Set length
|
|
* @var {number}
|
|
*/
|
|
'private _setLength': 0,
|
|
|
|
/**
|
|
* Current set position
|
|
* @var {number}
|
|
*/
|
|
'private _setPos': 0,
|
|
|
|
|
|
__construct: function( base_set, sample_size )
|
|
{
|
|
this._set = base_set;
|
|
this._samplesRemain = +sample_size || -1;
|
|
|
|
this._reset();
|
|
},
|
|
|
|
|
|
/**
|
|
* Randomizes a set using the Fisher-Yates shuffle algorithm
|
|
*
|
|
* @param {Array} set set to sort
|
|
*/
|
|
'virtual protected randomizeSet': function( set )
|
|
{
|
|
var i = set.length;
|
|
|
|
// simply prevent an infinite loop below
|
|
if ( i === 0 )
|
|
{
|
|
return set;
|
|
}
|
|
|
|
// simply loop through each element in the set, swapping each with a
|
|
// random index
|
|
while ( --i )
|
|
{
|
|
var r = Math.floor( Math.random() * ( i + 1 ) );
|
|
set[ i ] = [ set[ r ], ( set[ r ] = set[ i ] ) ][ 0 ];
|
|
}
|
|
|
|
return set;
|
|
},
|
|
|
|
|
|
/**
|
|
* Retrieve the next element in the set
|
|
*
|
|
* @return {string} next element in set
|
|
*/
|
|
'public getNextElement': function()
|
|
{
|
|
// return null once we have returned all of the requested samples
|
|
// (intentionally a 0 check, as this will be negative for an
|
|
// infinite number of samples)
|
|
if ( this._samplesRemain-- === 0 )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// reset once we're at the end
|
|
if ( this._setPos === this._setLength )
|
|
{
|
|
this._reset();
|
|
}
|
|
|
|
// return element from set (do not shift/pop, since we may need to
|
|
// repeatedly iterate through this list)
|
|
return this._set[ this._setPos++ ];
|
|
},
|
|
|
|
|
|
'private _reset': function()
|
|
{
|
|
this._setPos = 0;
|
|
this._set = this.randomizeSet( this._set );
|
|
this._setLength = this._set.length;
|
|
},
|
|
|
|
|
|
'protected getSampleSize': function()
|
|
{
|
|
return this._samplesRemain;
|
|
}
|
|
} );
|