SCRIPTING:

tatjana simic
THE ARRAYS REPORT
A somewhat powerful function: given a set of arrays, this script gathers a lot of data on them, taking avail both of standard array loops and of building up associative arrays to speed up the comparison processes.
You can then store in a global variable its returned values, such as associative arrays about what arrays the values recur in, what arrays miss what values, how many times certain values recur, and so on. Short codex and fast enough.
August 2003
{ @ }

The model above is Tatjana Simic
LOADS OF TATJANA SIMIC ON THE NET


PURPOSE
What the scripts are for

Although on Unitedscripters I present a really huge amount of scripts meant to manipulate arrays (for a list see this file), none the less it is no surprise: arrays (both normal ones and associative arrays) are the most powerful way, to date, to gather data meant to be handled as a family or as siblings; it is still the best way to group values meant to share some transversal property/ies which is pertinent to them all or which is dealt among them all throughout. No surprise therefore that a website devoted to provide you with scripts which are free, yes, but also more powerful than the average provided by many other sites, is then also strongly committed to array managements.
The script I feature here is named arraysReport and goes with an auxiliary smaller script named chainedArrays.
It would get in as its only argument an array whose each item must be an array again: that is, its only required argument is an array that as a chain links a family of Arrays meant to be scanned by the arraysReport.
Actually, the last statement is somewhat deceptive: the only argument that the arraysReport requires is, yes, an array, but should be arranged as such:
Array=new Array( ARRAYS, NUMBER )
That is, the passed array must be an array whose first entry [0] is the chain of arrays (an array which holds arrays) and the second one a number: such number represents the length of the longest array among those chained and passed: this number is necessary to the arraysReport for by its agency I can scan the list of arrays without arranging a loop for each of them but with one single loop set to scan by default until the lengthier length found: of course, when one of the chained arrays is shorter, the script would detect this on its own.
 
So, in order to ease your job, I provide you along with another script named chainedArrays which will do the job of producing the right format for you given a list of arrays either already chained or to be chained: More particularly:
  • chainedArray: it takes in as arguments a list of whatever amount of arrays, and it produces as returned output an array of three entries as follows:
    1. first entry (index [0]) is the whole set of arrays passed but now chained on another array that works as its backbone;
    2. the second entry (index [1]) is a number representing the length of the longest array found among the pool of the arrays passed as arguments to the function;
    3. the last third argument (index [2]) is a number representing the shorter length among the pool of the arrays passed as arguments to the function.
    chainedArray(array1, array2, array3 /*etc...*/);
    The function can understand whether by chance you passed a list of arrays that was already chained (it guesses it if you pass one argument alone) and in such case would only care to add to its output the two required numbers for the max and min lengths.
Before we switch to describe more in detail how the main script arraysReport works and describe in the tiniest details the format of its output, what it reports and how it can be used, and before featuring the test form where you can get better acquainted with its outputs providing inputs that you can custom, I find more appropriated furnishing you immediately with the codexes of the two functions; here they are:
 
THE CHAINEDARRAY & ARRAYSREPORT CODEX
anna kournikova
chainedArray
arraysReport
lines:
lines:
The model above is Anna Kournikova
LOADS OF ANNA KOURNIKOVA ON THE NET


HOW THE SCRIPT WORKS
How to invoke the arraysReport, and the format of what it returns

As I said the arraysReport needs the arrays meant to be inspected passed in a peculiar format. To make it easier I provided you also with the chainedArrays script. Thus having a set of arrays such as, for example (imagining that the values are all of the Number data type, just to make it simpler):
[1,2,3,4]
[5,6,7,8,9,10]
[9,8,7,6,10]
[1,2,1,1,3]
You just have to chain them by chainedArrays so that also their main length is derived:
chainedArrays(
[1,2,3,4],
[5,6,7,8,9,10],
[9,8,7,6,10],
[1,2,1,1,3]
)

chainedArrays would then return an Array of three entries as follows:
[0] is the list of arrays, chained on the backbone of a bigger array.
[1] is a number representing the max length of the longest array.
[2] is a number: it is not necessary but since we were there, I thought also to provide along with the smaller length, namely the length of the shorter array.
 
Such format is indispensable to the arraysReport only as long as the first two items returned by chainedArrays are concerned (namely [0] and [1]). Of course, you can still device such a format by yourself without taking avail of the chainedArrays function: but why not using it since it is here already ready?
So a nifty invocation of arraysReport on the list of arrays of our example would consist, exactly, into nesting the call to chainedArrays within the call to arraysReport as its only argument:
 
arraysReport(
   chainedArrays(
   [1,2,3,4],
   [5,6,7,8,9,10],
   [9,8,7,6,10],
   [1,2,1,1,3]
   )
);

 
I suggest to you to save the results produced by arraysReport in some globally defined variable, sort of:
yourVariable=arraysReport( chainedArray(array1, array2, array3 /*...*/) );
for they are a throve, and the returned object thus stored in yourVariable may allow you further inspections at a second time, in case you want to devise more functions on your own or arrays data mining based upon the results delivered by inspections of the overall report of the elements present in the arrays as provided by the arraysReport. It is extremely useful, for instance, if your intention is to calculate unions (items recurring in all of the arrays or in a few - detailing thus also which ones and where within them) or differences (item not recurring in all the arrays or in a few - and which ones) thus handling the arrays as emulations of sets or families.
If you are to do that, this assumes you got somewhat acquainted with the format of the matrix (array of arrays or array of objects or -our case- of both) returned by arraysReport, and which we're to see soon.
Remember that Objects can be scanned only by for-in loops and that these loops always scan producing an index in the String format.
 
Now, let's inspect its returned output. The reason it is so articulated is that it is meant to enable you to gather whatever information you may want about a family of arrays and their values either by addressing them by exploiting the property of associative arrays or by resorting to standard numerically indexed arrays, or both: the arraysReport would, for instance, return to you an array whose each index is the index of one of the passed arrays in the chain (a number, that is) and whose object held by each of such indexes is an object (associative array) indexed by the values found,
returned[Number][Mixed]
thus for each numerical index referring to an array you can instantly know, for each value, how many items of it are in the indexed array.
Also, it would return to you, for instance, the specular version of the just mentioned structure: an associative array whose each index is one of the values found among all the arrays (listed only once, even if it recurs manifold times throughout all the scanned arrays),
returned[Mixed][Number]
and each of such indexes would hold an array indexed by a number: in this way by merely addressing a value you may find on which arrays such value was present.
Eventually, it would also report what values shared by other arrays are not present in them, would report how many times each value is found, would report the indexes within each array where a value is found, would report what's the highest amount of recurrence for each value and where such highest amount is located (first array where the highest amount recurs).
 
As we saw, the arraysReport: it takes in one argument, which has to be an output in the chainedArray function format. Here is what it returns after invoked: an array of 8 items namely indexed from zero until index 7. Example:
var foo=arraysReport(
   chainedArrays(
   [1,2,3,4],
   [5,6,7,8,9,10],
   [9,8,7,6,10],
   [1,2,1,1,3]
   )
);
//you now have:
foo[0]; foo[1]; foo[2]; foo[3]; foo[4]; foo[5];
foo[6]; foo[7];
Here is in detail what each of them is, namely the type of data structure appended to each of such yielded entries, and how it can be scanned-inspected:
 
arraysReport RETURNED DATA STRUCTURE: array
[0]

Check present items addressing them by item Data Type
Object[M]=Array[N]=Array;
 
Each instance of M is one of the item found within the arrays: instance if the arrays entries contain an object, a string, a number, whatever, then such index M would report once an instance of such object, string, number, whatever and would provide about it data on where it recurs, how many times and the alike.
Each instance of N would be the Index of one of the chained arrays from zero onward untile the amount of arrays chained (length-1, as usual in programming) thus the meaning of the whole is: for such item checks within each array addressed by its numerical index in the chain of arrays the data about such item M.
More specifically, let's provide you with an over-simplified example, let's imagine a couple of sets as:
[5,8]
[5,10,5]
 
Keep in mind that the Arrays above could hold whatever data Type: I arranged both of them to hold only numbers just to simplify!
The output returned by arraysReport would store in the index 1 the following, analyzing it step by step:
 
returned[0]=Object;
returned[0][5]=Object; reports on element 5
returned[0][5][0]=Array; reports the presence of 5 in Array 0 namely the first Array;
returned[0][5][0].length= the amount of times 5 recurs in the first Array (in our case: once)
returned[0][5][0][0]= the first position within the first Array where element 5 can be found (that is, such value is a Number representing an Index within the first Array);
 
returned[0][5][1]=Array; reports the presence of 5 in Array 1 namely the second Array;
returned[0][5][1].length= the amount of times 5 recurs in the second Array (in our case: twice).
returned[0][5][1][0]= the first index position of element 5 in second Array
returned[0][5][1][1]= the second index position of element 5 in the second Array
 
returned[0][8]=Object; reports on element 8
etc... and so on for each item.
[1]

Check present items addressing them by chained Arrays Numerical Indexes
Array[N]=Object[M]=array
 
Each instance of N would be the Index of one of the chained arrays from zero onward untile the amount of arrays chained (length-1, as usual in programming).
Each instance of M is one of the item found within the arrays: instance if the arrays entries contain an object, a string, a number, whatever, then such index M would report once an instance of such object, string, number, whatever and would provide about it data on where it recurs, how many times and the alike.
Thus the meaning of the whole is: for such Array check within each item M addressed the data about such item in such Array.
More specifically, let's provide you with an over-simplified example, let's imagine a couple of sets as:
[5,8]
[5,10,5]
 
Keep in mind that the Arrays above could hold whatever data Type: I arranged both of them to hold only numbers just to simplify!
The output returned by arraysReport would store in the index 1 the following, analyzing it step by step:
 
returned[1]=Array;
returned[1][0]; accessing the first array (index 0) in the lot of those passed (namely Array [5,8]).
returned[1][0][5].length; checking in such array how many times number 5 recurred (our case: once).
returned[1][0][5][0]; checking in such array where number 5 recurred for the first time (index [0]).
etc... and so on for each array.
[2]

Check absent items addressing them by item Data Type
Object[M]=Object[N];
 
Each instance of M is one of the item found within the arrays, and reports in which arrays they were not present (absent, that is): instance if the arrays entries contain an object, a string, a number, whatever, then such index M would report once an instance of such object, string, number, whatever and would provide about it data on where it does not recur. Where it would not recur will be the numerical index labeled now as N of each array index in the chain of chained arrays where such item M was not found.
 
Since these indexes N are stored within an Object, you have to loop it if you want to loop it through a for-in loop, or you can instantly address it without looping for an Object is an associative array whose presence of an element can be simply checked without looping by a mere call to:
if(typeof(returned[2][M][N])!="undefined"){/*item M while checking ABSENCES from array N is not undefined, namely such item M was NOT present within array indexed as N*/}
Use typeof to perform such checks. It assumes you're unsure whether item M is present in array indexed as N, but not that you're unsure about the presence, somewhere in the whole chain, of item M.
If you're unsure of that too, perform a double typeof check:
if(typeof(returned[2][M]) != "undefined" && typeof(returned[2][M][N])!="undefined"){/*neither M nor N are undefined, namely such item M was NOT present within array indexed as N*/}
Or, arguably even better and safer, check first if the item you're so much unsure about is within the returned[0] records: that is:
if(typeof(returned[0][M]) != "undefined" && typeof(returned[2][M][N])!="undefined"){/*neither M nor N are undefined, namely such item M was NOT present within array indexed as N*/}
 
More specifically, let's provide you with an over-simplified example, let's imagine a couple of sets as:
[5,8]
[5,10,5]
 
Keep in mind that the Arrays above could hold whatever data Type: I arranged both of them to hold only numbers just to simplify!
The output returned by arraysReport would store in the index 2 the following, analyzing it step by step:
 
returned[2]=Object;
returned[2][10]=Object; reports absences of element 10
returned[2][10][0]=0; reports the absence of 10 in Array indexed by Number 0 (reports such index both as the index and as the value held by it!). If such indexing by [0] would have resulted undefined, it would have meant that number 10 is would have not been absent from the array indexed as [0].
etc... and so on for each item and Array.
[3]

Check absent items addressing them by chained Arrays Numerical Indexes
Array[N]=Object[M];
 
Each instance of N is an Array index of the chained arrays: for each of them an object reveals if the item M was not present (absent) from Array N.
 
Since these indexes M are stored within an Object, you have to loop it if you want to loop it through a for-in loop, or you can instantly address it without looping for an Object is an associative array whose presence of an element can be simply checked without looping by a mere call to:
if(typeof(returned[3][N][M])!="undefined"){/*in Array N item M is not undefined, namely such item M was NOT present within array indexed by N*/}
 
More specifically, let's provide you with an over-simplified example, let's imagine a couple of sets as:
[5,8]
[5,10,5]
 
Keep in mind that the Arrays above could hold whatever data Type: I arranged both of them to hold only numbers just to simplify!
The output returned by arraysReport would store in the index 2 the following, analyzing it step by step:
 
returned[3]=Array;
returned[3][0]=Object; reports what is absent from Array indexed as zero within the chain of passed arrays.
returned[3][0][10]=10; reveals absence of item 10 in Array [0] (reports such item both as the index and as the value held by it!).
etc... and so on for each item and Array.
[4]

Amount of times an item is absent
Object[M]=Number;
 
For each instance of item M reports in how many arrays it was not found (absent).
Its conceptual integration, namely in how many arrays item M was found is given by:
returned[5][M];
[5]

Amount of times an item is present
Object[M]=Number;
 
For each instance of item M reports in how many arrays it was found (present).
Its conceptual integration, namely in how many arrays item M was not found is given by:
returned[4][M];
 
Please note that this count does not say how many times the item recurred in all the arrays: for instance in a chain of arrays such as:
[1,2,2]
[3,4]
[2,6,7]
[2,2,2,4]
the returned[5][2] value (namely how many times item 2 -still a number to simplify, but it can be whatever data type- recurs) yields not as a result 6 times, but yields 3, to signify there are three arrays meant as a whole where such value 2 was found at least one time.
 
As for where item M recurs in the arrays, see returned[0] and returned[1].
[6]

Maximum amount of recurrences for items
Object[M]=Array(Number1, Number2);
 
Given item M, Number 1 says the highest amount of times it was found within an array, and Number2 says which is the index of such array where such highest amount recurred.
It indexes only the first array where such recurrence was found:
[1,2,2]
[2,2,2,6,7]
[3,4]
[2,2,2,4]
returned[6][2] (that is, checking where the highest recurrence of item 2 is) would be an array holding:
[3,1]
meaning that number 2 recurred at most 3 times within one single array and that the first Array where such recurrence was met was that indexed by index 1.
 
The minimum amount for an item existent within the passed arrays (that is, which is typeof(returned[0][M]!="undefined") is always either 1 or higher.
[7]

Input
This entry just returns to you the passed input (that is, the chained array) for your convenience in case you may need it again. If the passed array was also defined as a variable globally existing, there is a pointer relation between the global object and this returned image.


THE TEST FORM
Check the output yourself providing the inputs yourself

arraysReport TEST FORM
kandinsky
Wassily Kandinsky, Winter 1
Provide list of whitespace separated elements, or use the following ones:





     
van Gogh
Vincent Van Gogh, self protrait
checks returned[0]:
 

matisse
Henry Matisse, creole dancer
checks returned[1]:
 

turner
William Turner, The Exile And The Rock Limpet
checks returned[2]:
 

kandinsky
Wassily Kandinsky, Moscow 1
checks returned[3]:
 

checks returned[4]:
 

checks returned[5]:
 

checks returned[6]:
-note: remember that arrays are indexed starting count from 0-
 

returned[7] is the input:
kandinsky
Wassily Kandinsky, Composition VI