SCRIPTING:

a Heinrich Fussli painting
a Heinrich Fussli painting

EXTRACT DISHOMOGENEOUS SUBSET FROM ARRAY
Functions for processes such as dealing cards. They may be haunting for beginners.
If you have a certain amount of entries in an array and you either want to extract a subset of these entries being sure they are all different or you want to return the original array without a random subset of its own entries, this is definitively your lot.
September 2001
{ @ }



Your functions and their purposes
It will draw a set of entries from a bigger array being sure no one of the picked entries is the same as one already picked. Another function would instead allow for extractions of identical items too.

The first of these two functions deals a specified amount of entries randomly drawn from an array. It makes sure that all the extracted entries are different from, each other, that is never twice the same value.
Of course, this would work smoothly especially in those cases where all the entries of the input array from which you want to extract items are different from each other; or, at any rate, this function is fit for all those cases where, although having an input array where a few duplicates may be present, you none the less want to extract a subset of it being sure such clipped subset is composed of items all different from each other.
Given its goal, you may want to have a look also to another subroutine which is the one meant to shuffle an array - click.
But here is your subroutine. Here it is below:

The dealEntries Function
a Heinrich Fussli painting
a Heinrich Fussli painting


The main setback with the function above, namely the setback you have to cope with whenever you want to extract a fully dishomogeneous subset from an Array, is that you should make sure prior to everything else that within the input array there are indeed enough different elements (entries) to return an output of the given amount of differentiated items.
In other terms, if you want to extract a dishomogeneous subset of, say, 3 items form an array of 7 items whose first 5 are all zeros, and whose last two are both number one, then you will never generate an output of three entries, and the dealEntries function would enter an infinite loop.
I could have nested in it a validation of the input array, but since such validation requires a scanning of the input array which you might judge useless (case in point: you already know and are absolutely sure that all the entries of the input array are different from each other), I decided to provide you with a separate smaller function to perform such validation, thus you can make it only if you have reasons to believe it is wise or advisable. Such function is reproduced below, requires still two arguments, the input array and the amount you want to get out of it, and returns either boolean true (the input array can eventually yield the amount of items as an output) or boolean false. The function's name is checkEntries

The checkEntries Function

a Heinrich Fussli painting
a Heinrich Fussli painting
withespace separated array:

Of course, there can be cases where you want to extract a subset, but you also want to allow for duplicates inside the output.
Please note: in this case I assume that what you want (and arguably this is exactly what you meant) is not that a recursion meant to glean entries from the input array in order to build a subset could end up gathering twice the same entry: what I assume is that you do want one entry from the original input array being taken once and only once, none the less in case the original array would carry duplicates you may want to allow for the extracted subset the presence of such duplicates if it happens that in the random extraction process an item from the input array which has never been grabbed before may be grabbed as well - regardless of the fact such value is already present in the output as a consequence of a previous (and different) entry of the input array already taken in.
In this case you should not use the function exposed above because the function above excludes any chance of getting in twice the same value even if duplicates are present in the input array, but conversely you'd use the folowing one named dealEntries2:

The dealEntries2 Function

a Heinrich Fussli painting
a Heinrich Fussli painting


Comments
How it works and gets implemented

  1. The functions want two arguments:
    Torrid Taylor
    the array from which entries have to get drawn, and the amount of entries which have to get drawn (such as: from an amount of 60 cards, gets 5 cards...)
  2. If by chance the amount is not set, we return an empty array (that is: no drawning was possible at all) and we return also the full original array passed as an argument. In fact you have to keep in mind that this function returns an array of two entries, the first of which is the subset, and the second of which is the original array without the extracted subset values
    Thus when you invoke the array (see later on) you will have to specify either an index of [0] or of [1]
    On the other hand if by chance you set an amount higher than the given array we return as dealt the whole of the entries and as remains an empty array.
  3. We build an inner array, named dealt which will carry the entries extracted from array argument.
    As long as dealt length is not equal to the specified amount, we insist picking a random entry from the array passed as argument.
    We than verify that this entry is not already within dealt (in the case of the first function dealEntries) since our purpose is exactly to deal a subset of items which must be all different: the same item must not be extracted twice. Needless to say this appraoach is different for dealEntries2
  4. If the item is not within the dealt array, we add it ot it.
    When alongside this process it occours that the dealt array gets the specified length equalling the amount argument, we stop the while loop; this latest loop in fact will go on randomizing and picking at random entries as long as the length of the dealt array won't be of the specified amount.
  5. I eventually proceed to build up the remains array which will carry what would remain in the array passed as an argument once stripped of the dealt elements.
    In such fashion you can extract from this subrouitne whatever lot you prefer, only one (dealt or remains) or both of them.
    In fact the subroutine returns an array whose first entry is the dealt entries collections, and the second is what would remain in the argument array
    Please note that the original array passed as an argument goes unaffected since we make copies: if you want to affect it, you'd need a specific assignment.
     
    Invoke the function(s) as follows:

    dealEntries(testArray,5)[0]
    //or:
    dealEntries(testArray,5)[1]
    Even better, you may first assign the function to a variable and later index this latter variable, so to produce consistent sets of dealt and remains:

    var foo=dealEntries(testArray,5);
    //now the dealt are foo[0], and the remains are foo[1]
    Whereas number 5 is just an amount (could be whatever number except a number higher than the array length: in such case the function just returns all the entries as dealt and an empty array as remains.
If you want a fake array to make a test from within an alert box, try this snippet:
var testArray=new Array("ace","king","queen","jack","10","9","8","7","6","5","4","3","2")

then invoke the alert, for instance, like follows, and you will see everytime the 5 entries are different and without duplicates, unless you have used dealEntries2 and the input array included duplicates and ita happened they got picked for the output (and if you use index [1] you'll see the remains are shaped accordingly):
alert(dealEntries(testArray,5)[0])

TEST FORM
Eugene Smith, Okinawa (part.)
a Eugene Smith photo
Use dealEntries » | dealEntries2 »
white space separated vector:

amount: