Post by JJI frequently need to use one dimensional arrays for e.g.: search a value in
a array, sort the array, copy part or whose array, etc.
Array, Dim, Erase, IsArray, LBound, ReDim, and UBound.
I had to create my own functions for those. e.g. for searching a value in an
function indexof(arr, val)
indexof = -1
for i = 0 to ubound(arr)
if arr(i) = val then
indexof = i
exit function
end if
next
end function
dim arr(2)
arr(0) = 3
arr(1) = 9
arr(2) = 1
wscript.echo indexof(arr, 5) '-1
wscript.echo indexof(arr, 1) '2
So, if anyone know a better way to work with array, I'm all ears.
Currently, I had keep a VBS file that contains subroutines and functions, as
a library. I'd copy+paste any required code from the file into the main VBS
script in order to make them available. This can be a tedious task when many
functions are involved. Moreover the main VBS script would be cluttered.
How did you do for this case?
Switch your calling scripts to WSF file format and in them refer to your
shared array routines library vbs file via a <script> tag. You can include
a file path & name the file .inc instead of .vbs if it helps you remember.
Include it early on IN EACH JOB in the WSF & it will be executed before
your jobs' other scripts. Don't put any naked commands in it, as they
will be executed, just define constants & routines you may want to call.
<?xml?>
<package>
<comment>Jobs using my array library ArrayLibrary.vbs
cscript TestArray.wsf //job:Job1
cscript TestArray.wsf //job:Job2
</comment>
<resource id="1234">Text String or Number</resource>
<resource id="ArraySize">25</resource>
<job id="Job1">
<comment>First test of array routine</comment>
<object id="WshShell" progid="Wscript.Shell" />
<object id="FSO" progid="Scripting.FileSystemObject" />
<reference object="Wscript.Shell" />
<reference object="Scripting.FileSystemObject" />
<script language="VBScript" src="ArrayLibrary.vbs"/>
<script language="VBScript">
<![CDATA[
' WshShell & FSO global objects defined + all their typelib'd constants
' ArrayLibrary.vbs ran so all its routines are defined to me.
Dim I , J , arrTest()
ReDim arrTest( getResource("ArraySize") )
J = UBound(arrTest) ' make array most unsorted possible (rev sort).
' note LBound() UBound() & Len() are instant memory lookups
' and even UBound() - 1 is only calc'd 1 time for the For Loop's existance.
' no need to assign them to variables.
For I = LBound(arrTest) To UBound(arrTest)
arrTest(I) = J : J = J - 1
Next
SortArray(arrTest) ' call sort routine in ArrayLibrary.vbs
wscript.echo Join(arrTest, vbLf) ' show it 1 line per entry.
'if you Quit here, the following script in this job will never run.
' WScript.Quit
]]>
</script>
<script language="JavaScript">
<![CDATA[
// a javascript routine can go here.
function ReverseDemo(){
var a, l; //Declare variables.
a = new Array(0,1,2,3,4); //Create an array and populate it.
l = a.reverse(); //Reverse the contents of the array.
return(l); //Return the resulting array.
}
]]>
</script>
</job>
<job id="Job2">
<comment>Second test job of array routine</comment>
<reference object="Scripting.Dictionary" />
<object id="oDict" progid="Scripting.Dictionary" />
<comment>library .inc now in includes dir next to script dir</comment>
<script language="VBScript" src="..\includes\ArrayLibrary.inc"/>
<script language="VBScript">
<![CDATA[
wscript.echo "hello from TestArray Job2"
Const BinaryCompare = 0 ' same as vbBinaryCompare
Const TextCompare = 1 ' same as vbTextCompare
Const DatabaseCompare = 2
Dim arrKeys, arrItems
With oDict
' Optional: can be 0 (Binary), 1 (Text), 2 (Database)
' Values greater than 2 can be used for specific Locale IDs (LCID).
' use binary if case sensitive keys, use text if case insensitive keys.
' .CompareMode = 0
.Add "key" , "item" ' add a new key & Item pair to the dictionary.
' .Count ' # of key/item pairs in dictionary
' .Exists(key) ' bool True if key exists in dict
' .Key(key) = NewKey ' change key value for an item.
' myItem = .Item(key) ' get an item value for a key.
' .Item(key) = NewItem ' set an item value for a key.
' .Remove(key) ' remove a given Key and its Item entry from the dict.
' .RemoveAll ' delete all keys and values
' its faster to Set oDict = Nothing : Set oDict = CreateObject("Scripting.Dictionary")
' copy key and item lists into new 1D arrays!
arrKeys = .Keys
arrItems = .Items
.RemoveAll
End With ' oDict
WScript.Echo Join(arrKeys) , Join(arrItems)
Erase arrKeys : Erase arrItems
' use .Count as key 0..N For an ordered FIFO list of keyless items.
With oDict
For I = 0 To 10 : .Add .Count , "Item " & CStr(I) : Next
' copy key and item lists into new 1D arrays!
arrKeys = .Keys : arrItems = .Items
End With ' oDict
' ForEach walks dictionary KEYS in order ADDED, use .Item(v) for matching value.
For Each v In oDict
WScript.Echo v , oDict.Item(v)
Next
WScript.Echo Join(arrKeys) , Join(arrItems)
' test a function in ArrayLibrary.inc
WScript.Echo IndexOf(arrKeys,6)
Erase arrKeys : Erase arrItems
Dim ab(2,3)
ab(0,0) = "0,0" : ab(0,1) = "0,1" : ab(0,2) = "0,2" : ab(0,3) = "0,3"
ab(1,0) = "1,0" : ab(1,1) = "1,1" : ab(1,2) = "1,2" : ab(1,3) = "1,3"
ab(2,0) = "2,0" : ab(2,1) = "2,1" : ab(2,2) = "2,2" : ab(2,3) = "2,3"
' ForEach on a matrix cycles thru all of the leftmost index first
' then increments the next dimension to the right and repeats, then
' it increments the next dimension to the right of that upto 60 dimensions
' Dim array1(columns, rows) to cycle thru all columns before moving to next row.
' Dim array1(rows, columns) to cycle thru all rows before moving to next column.
I = 0
For Each v In ab
WScript.Echo "Entry: ", I , v , " should be at " , I Mod 3 , I \ 3
I = I + 1
Next
]]>
</script>
</job>
</package>