Associative Array Using Hash Table
Richard D. Clark rickclark58@gmail.com

This FreeBasic AsArray Object implements an associative-like array using a hash table for storing and retrieving data. The data is contained within a Data Object that is a variant-like data structure that accepts any of the standard FreeBasic data types. The Data Object overloads the assignment and equality operators so that direct assignment and comparisons are possible.

The AsArray Object exposes has methods to insert, find and delete data based on a key. The key is also a Data Object, so any type of value may be used as a key, although it is recommended that strings and integer values be used as key to avoid ambiguous entries.

Namespace

The AsArray and Data Objects are contained within the fbasarray Namespace. You must qualify membership access using either fbasarray.method or by using the Using directive. To create an instance of a Data Object and AsArray Object use the following symtax.

#Include "asarray.bi"

Dim myAsarray As fbasarray.asarray
Dim myKey As fbasarray.dataobj
Dim myData As fbasarray.dataobj

Setting the Table Size

The hash table is set to 200 as a minimum size. You can create larger tables by passing the table size to the AsArray constructor. The table size is only limited by available memory.

Dim myAsarray As fbasarray.asarray = 500

Checking for Proper Initialization

You can check to make sure the table was created properly by examining the IsInit proeprty.

'Make sure table was properly intialized.
If myAsarray.IsInit = fbasarray.FALSE Then
   Print "Could not initialize the asarray object."
   Sleep
   End
EndIf

Getting the Table Size

You can determine the current table size by examining the TableSize property.

'Print the current table size.
Print "Table size: "; myAsarray.TableSize

Inserting Data Into the Table

You can insert data into the table using the InsertKeyData method by passing two data objects that represent a key and data.

'Insert some data based on integer key.
myKey = 55
myData = "VAR1"
ret = myAsarray.InsertKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not insert data into asarray object."
Else
   Print "Data added to asarray object."
EndIf

'Insert some data based on single key. Use suffix to force single.
myKey = 55.0f
myData = "VAR2"
ret = myAsarray.InsertKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not insert data into asarray object."
Else
   Print "Data added to asarray object."
EndIf

Even though the two keys hold the same numerical value, they are considered different keys because the data types are different. Tow Data Object are only equal if they have the same data type and the same value.

If an attempt is made to insert a duplicate key (sane data type and value), InsertKeyData will retun FALSE (0) and the data will not be inserted into the table.

Retrieving Data from the Table

Use the GetKeyData method to retrieve data from the AsArray object.

'Get the data for each key value.
mykey = 55
ret = myAsarray.GetKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not find data in asarray object. Key = " & myKey
Else
   Print "Data " & myData & " found in asarray using key " & myKey & " which is type " & myKey.DataType & "."
EndIf

If the key is not found, GetKeyData will return FALSE (0).

Changing Data in the Table

You can change data in the table by using the SetKeyData.

'Change the integer key data.
myKey = 55
myData = "VarInt"
ret = myAsarray.SetKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not change data in asarray object."
Else
   Print "Data changed successfully."
EndIf
'Get the new data.
mykey = 55
ret = myAsarray.GetKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not find data in asarray object. Key = " & myKey
Else
   Print "Data " & myData & " found in asarray using key " & myKey & " which is type " & myKey.DataType & "."
EndIf

Deleting a Key-Data Pair

You can delete an entry in the table using the DeleteKeyData.

'Delete the integer key.
myKey = 55
ret = myAsarray.DeleteKeyData(myKey)
If ret = fbasarray.FALSE Then
   Print "Could not delete data in asarray object."
Else
   Print "Key-data deleted."
EndIf
'Try and get the deleted data.
mykey = 55
ret = myAsarray.GetKeyData(myKey, myData)
If ret = fbasarray.FALSE Then
   Print "Could not find data in asarray object. Key = " & myKey
Else
   Print "Data " & myData & " found in asarray using key " & myKey & " which is type " & myKey.DataType & "."
EndIf

Checking if a Key Exists

You can check for the existence of a key in the table by using the FindKey method.

'Find the float key.
myKey = 55.0f
ret = myAsarray.FindKey(myKey)
If ret = fbasarray.FALSE Then
   Print "Could not find key " & myKey & "."
Else
   Print "Found key " & myKey & " which is type " & myKey.DataType & "."
EndIf

AsArray Public Interface

   Declare Constructor (tsize As Integer = MINTABLESIZE) 'Sets defaults for table. 
   Declare Destructor () 'Calls Destroy.
   Declare Property IsInit () As Integer 'Returns initok.
   Declare Property TableSize () As Integer 'Returns dsize.
   Declare Function FindKey(k As dataobj) As Integer 'Returns TRUE if key exists.
   Declare Function InsertKeyData(k As dataobj, dt As dataobj) As Integer 'Inserts data into table.
   Declare Function GetKeyData(k As dataobj, dt As dataobj) As Integer 'Returns data from table.
   Declare Function SetKeyData(k As dataobj, dt As dataobj) As Integer 'Sets data at key.
   Declare Function DeleteKeyData(k As dataobj) As Integer 'Deletes key and data.

DataObj Public Interface

   Declare Constructor ()
   Declare Destructor ()
   Declare Property DataType () As cdatatype  'Returns the data type.
   Declare Sub ClearData ()
   Declare Sub SetData (rhs As dataobj)        'Sets data of object.
   Declare Sub GetData (rhs As dataobj)        'Gets data of object.
   Declare Operator Let (rhs As dataobj)       'Assignment operator.
   Declare Operator Let (rhs As Byte)            
   Declare Operator Let (rhs As UByte) 
   Declare Operator Let (rhs As Short) 
   Declare Operator Let (rhs As UShort) 
   Declare Operator Let (rhs As Integer) 
   Declare Operator Let (rhs As UInteger) 
   Declare Operator Let (rhs As Long) 
   Declare Operator Let (rhs As ULong) 
   Declare Operator Let (rhs As LongInt)
   Declare Operator Let (rhs As ULongInt)
   Declare Operator Let (rhs As Single)
   Declare Operator Let (rhs As Double)
   Declare Operator Let (rhs As String)
   Declare Operator Cast () As Byte  'Cast to data type.
   Declare Operator Cast () As UByte
   Declare Operator Cast () As Short
   Declare Operator Cast () As UShort
   Declare Operator Cast () As Integer
   Declare Operator Cast () As UInteger
   Declare Operator Cast () As Long
   Declare Operator Cast () As ULong
   Declare Operator Cast () As LongInt
   Declare Operator Cast () As ULongInt
   Declare Operator Cast () As Single
   Declare Operator Cast () As Double
   Declare Operator Cast () As String
   Operator = (lhs As dataobj, rhs As dataobj) As Integer 'Equality operator

File List

testarr.bas : Test program.
asarray.bi : Hash table.
dataobj.bi : Data object.
asarray.fbp : fbEdit project file.

License

The MIT License

Copyright (c) 2011, Ruchard D. Clark

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

http://www.opensource.org/licenses/mit-license.php
