-
September 13th, 2002, 09:10 AM
#1
Arrays Tutorial (+free source)
It's Friday. It's 7am. I have at least another half an hour before my higher brain functions begin to react to the coffee. It's tutorial time.
Overview
In this outing I'm going to be looking at the basis of all real programming - arrays. Every programming language uses arrays. An array is a declared variable in a program that can hold many values. The individual values held within the variable are accessed using the ordinal of the values position within the array eg. variable(0). In this instance the ordinal, 0, would return the first (arrays are 0 based) value in the array variable.
Static arrays
Think of a single dimension array as a list. Consider the following snippet:
Code:
dim fruit(2)
fruit(0) = "apple"
fruit(1) = "orange"
fruit(2) = "banana"
This snippet declares the array fruit as having 3 values (0 through 2) and sets a value for each ordinal. This is a static array because the number of items that the array hold is fixed by the DIM statement. But in the real world we seldom have a use for static code such as this. More often we want arrays to hold an number of values that can only be determined at runtime.
Single dimesion arrays
Let's crete our array of fruits again but this time make it dynamic, so that it can hold an indeterminate number of items.
Code:
'Declare our array
fruit = array
'Add a new value to our array.
redim preserve fruit(ubound(fruit)+1)
fruit(ubound(fruit)) = "apple"
redim preserve fruit(ubound(fruit)+1)
fruit(ubound(fruit)) = "orange"
redim preserve fruit(ubound(fruit)+1)
fruit(ubound(fruit)) = "banana"
What just happened? Ok - first we declared our array. Using the syntax above the array is created empty. To add the first item to our list we need to tell the array to make a space for our new value. This is done using the REDIM statement, which re-dimensions the array. By using the PRESERVE keyword we tell the array to remember all previously stored values. If we ommit the preserve keyword any data that already exists in our array is lost.
We can find out how many values an array holds using the UBOUND keyword. UBOUND(anArray) tells us how many items there are in teh array anArray. Because arrays are 0 based the number of items in a single dimesion array always equals UBOUND(anArray)+1. So the value of fruit(ubound(fruit)+1) will equal 0, the number of items currently held in the array fruit +1. The line fruit(ubound(fruit)) = "apple" sets the new value that we have created (at ordinal 0) in the array to "apple".
Therefore:
Code:
redim preserve fruit(ubound(fruit)+1)
means create a new value 1 greater than the current number of items in the array, keeping all the existsing values and:
Code:
fruit(ubound(fruit)) = "apple"
Sets the value of the newly created item.
Multidimensional arrays
You can have arrays with many dimensions. Imagine a 2 dimensional array as a table. Imagine a 3 dimensional array as a cube. Try not to imagine a number of dimensions large than 3 however because it is the prime cause of spontanious human combustion. I think you can have a riduculous number of arrays in VB (20? maybe) but certainly enough that you could never use them. Arrays with more than 3 dimensions are very rarely used because the human mind has difficulty thinking in more than 3 dimensions. If someone ever asks you for more than 3 dimensions ask for mental insurance. You'll need it. But I digress.
Once again let's start with the static version:
Code:
'It's a table - 3 cells wide by three cells high
'Think of this as x,y axis
dim aTable(2,2)
atable(0,0) = "0,0"
atable(0,1) = "0,1"
atable(0,2) = "0,2"
atable(1,0) = "1,0"
atable(1,1) = "1,1"
atable(1,2) = "1,2"
atable(2,0) = "2,0"
atable(2,1) = "2,1"
atable(2,2) = "2,2"
Once again this code is not very useful because it is static. So how can we make it dynamic? When using multi dimensional arrays we can still use our UBOUND keyword. With multidimesional arrays the syntax of the UBOUND is slighly different however:
Code:
UBOUND(anArray,Dimension)
Where anArray is the array that you wish to find the itemcount for and dimension is the dimension number.
An example. To get the upper bound of our x and y dimensions above we would use the following:
Code:
ubound(aTable,1)
ubound(aTable,2)
We cannot however us the PRESERVE keyword when re-decalring multi dimesional arrays and so the dynamic version of the above code is a bit more sticky. We can however get round the problem by writing a function that:
1...Creates a tempoary array of the right dimensions
2...Copies the old data into the tempoary array
3...Adds the new data to the tempoary array
4...Returns the tempoary array.
The function might look like this:
Code:
aTable = array
aRow = array
aRow = ("Apples","Green","pips")
aTable = AppendRecord(aTable,aRow)
aRow = ("Oranges","Orange","pith")
aTable = AppendRecord(aTable,aRow)
aRow = ("Bananas","Yellow","peel")
aTable = AppendRecord(aTable,aRow)
for y = 0 to UBOUND(aTable,1)
for x = 0 to UBOUND(aTable,2)
echo aTable(y,x) ' Think (Row,Column)
next
next
Public Function AppendRecord(p_Table,p_Record)
temp = array
'p_table is a 2 dimesional array
'p_Record is a 1 dimesional array
'p_record will be treated as a row and added to the
'end of the p_table array
'Create an empty array of correct new dimensions
redim temp(ubound(p_Table,1)+1, ubound(p_record))
'Add the p_Table values to temp
for y = 0 to ubound(p_Table,1)
for x = 0 to ubound(p_Table,2)
'Copy the value at cell y,x from p_Table to temp
temp(y,x) = p_Table(y,x)
next
next
'**Create a new record in the array
'Iterate through fields in passed array adding to the temp array
for n = 0 to ubound(p_record)
temp(ubound(temp,1),n) = p_record(n)
next
'Set the new values in the p_Table Array
AppendRecord = temp
End Function
Directional sorting of 2 dimensional arrays
And now, for those of you who havn't given up, here's an ASP class that I use to sort 2 dimensional arrays (tables). Once you've got your 2 dimensional array (or table) you will probably want to be able to sort it, either into ascending or decending order, and using the column ordinal to sort by. This code is written in a class so that I can instantiate a copy of it for within any other script without re-writting this code.
[b]Usage[b]
Code:
SortArray(aArray,OrderBy,Dir)
aArray - 2 dimensional array
OrderBy - Ordinal of column to sort by - default 0
Dir - Direction to sort in ("ASC"/"DESC") - default "asc"
The class file!
Code:
<%
'<----- VBScript Class By NTSA
'<----- www.ntsa.org.uk
'<----- Class Name : ArrayCls
'<----- Compile Date : 11/09/2002
Class ArrayCls
Public function SortArray(aArray,OrderBy,Dir)
'aArray - 2 dimensional array
'OrderBy - Ordinal of column to sort by
'Dir - Direction to sort in (ASC/DESC)
'If sort direction is ommitted or not asc or desc then set to asc
dir = lcase (dir)
if dir = "" or (dir<>"asc" and dir<>"desc") then dir = "asc"
if len(orderby) = 0 then orderby = 0
san = 0
do
changed = false
for row = 0 to ubound(aArray,1)-1
select case AlphaCompare(aArray(row,OrderBy),aArray(row+1,OrderBy))
case 0
'Both the same
case 1
'row row is alpha< than row row+1
IF dir = "desc" then
aArray = SwapRows(aArray,row,row+1)
changed = true
end if
case 2
'row row+1 is alpha< than row n
if dir = "asc" then
aArray = SwapRows(aArray,row,row+1)
changed = true
end if
end select
next
san = san + 1
loop until changed = false or san = ubound(aArray,1)
IF san => (ubound(aArray,1)*ubound(aArray,1)) THEN
response.write "failed sanity check!
"
end if
SortArray = aArray
end function
'**************
'**Private functions
private function SwapRows(aArray,row1,row2)
temp = array
'Copy aArray into a temp variable
redim temp(ubound(aArray,1),ubound(aArray,2))
for y = 0 to ubound(aArray,1)
for x = 0 to ubound(aArray,2)
temp(y,x) = aArray(y,x)
next
next
'Iterate throgh the colums
for n = 0 to ubound(aArray,2)
'Swap to row values
temp(row1,n) = aArray(row2,n)
temp(row2,n) = aArray(row1,n)
next
'Return the new array
SwapRows = temp
end function
private function AlphaCompare(val1,val2)
'Compare val1 and Val1
' - returns 0 for same
' 1 if val1 is top
' 2 if val2 is top
val1 = lcase(trim(val1))
val2 = lcase(trim(val2))
if val1 = val2 then
AlphaCompare = 0
exit function
end if
len1 = len(val1)
len2 = len(val2)
if len1 < len2 then
checkchars = len1
'len1 is shorter so the default
'(if everything else the same) is 1
AlphaCompare = 1
else
checkchars = len2
'len1 is shorter so the default
'(if everything else the same) is 2
AlphaCompare = 2
end if
FOR n = 1 to checkchars
checkchar1 = asc(mid(val1,n,1))
checkchar2 = asc(mid(val2,n,1))
if checkchar1 < checkchar2 then
AlphaCompare = 1
exit function
end if
if checkchar2 < checkchar1 then
AlphaCompare = 2
exit function
end if
next
end function
End Class
%>
\"I may not agree with what you say, but I will defend to the death your right to say it.\"
Sir Winston Churchill.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|