LIST Object Updated: Oct 24, 2008 The LIST object facilitates creation and use of lists of text strings. Unlike some string list implementations using "atom" API calls, HotBasic LIST items can be any length within the practical size of user RAM. Please see hotlist.bas for example code. In HotBasic, any dimensioned STRING or MEMORY object can be used as a LIST. Why? You deserve it. While this flexibility is available, if you are more comfortable, just dimension STRING's, MEMORY's and LIST's, as you might already have in existing code, and use these objects conventionally. The conventional members of the LIST object are presented below. In addition, MEMORY properties and methods apply and can be used for special purposes if appropriate. PROPERTIES (Read/Write): ~~~~~~~~~~ ~~~~~~~~~~~~~ Length Length in bytes of LIST. ListLength = MyList.Length IF MyList.Length THEN 'List is not empty Position Current position for next read/write Note: In conventional LIST usage, .Position should not be changed, because .Position always equals .Length so .AddItems works. PROPERTIES (Read Only String): ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ Build (first_item, last_item, delimiter$) Note: Build a new string$ using LIST first_item to last_item. In the new string, the LIST items will be separated by delimiter$ Item (index) Assign LIST item index to string$ This$ = MyList.Item(i) 'i is 0-based .Item index Note: For sequential reads, .ReadLine is much faster: MyList.Position = zero WHILE MyList.Position < MyList.Length r$ = MyList.ReadLine 'code END WHILE PROPERTIES (Read Only Numeric): ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ Handle Memory handle of object stream data IndexOf (string$) Finds index of string$; 0 to .ItemCount; Returns -1 if string$ not found in LIST. Note: IndexOf is a basic "lookup" function. You may not care what the index of string$ is, but rather want to know if it exists. IF MyList.IndexOf("Mary") < 0 THEN PRINT "We haven't met yet" To avoid duplicates in a LIST, one can IF MyList.IndexOf(LookUp$) < 0 THEN MyList.AddItems LookUp$ RapidQ Basic and "atom" APIs do, I think, non-case-sensitive string item comparisons. In many cases, this is desirable, to lookup names of people or things -- Bolt size 10 or BOLT size 10? In such cases, one can just make a copy of a LIST like this: UCList = UCASE$(MyList) 'or LCList = LCASE$(MyList) ItemCount Item count of LIST; same as .LineCount Note: Many text files lack a trailing CRLF and therefore are not valid LIST database files and .ItemCount or .LineCount will not be correct. Your program may check LIST file integrity and fix malformed files: a$.loadfrom file "data.lst" if right$(a$,2)<>crlf then a$.position=a$.length: a$.additems null a$.savetofile "data.lst" 'save fixed file end if 'code LineCount Line count of LIST Pointer Address of LIST stream data Ram Bytes of memory currently allocated for LIST use Note: If more memory is required, it is automatically allocated as write methods add data to the stream object. Use of .Clear or .Close is recommended when computing is completed on large streams to free memory that is not immediately used further by the application. After .Close, the dimensioned stream still exists for further use. METHODS Arguments & Comments ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ AddItems (string$) Adds string$ to LIST. MyList.AddItems string$ AddList (list) Adds list to LIST. MyList.Additems MyOtherList Clear Clears data and frees allocated RAM if > about 256 bytes s$.Clear 'same as s$="" or s$=NULL Close Clears data; same as .Clear Decrypt Decrypts data; obviously, do this first if data encrypted DelItems (index[, index]) Deletes LIST item(s) with specified indeces MyList.DelItems 3, 6, 8 Encrypt Encrypts data; obviously, this is last method used before save Note: an optional key argument -- any numeric expression -- may be used with .Encrypt and .Decrypt. MyList.Encrypt key 'code MyList.Decrypt key 'same key value as used with .Encrypt ExChange (index1, index2) Exchanges items index1 and index2 in LIST ExtractRes (resource) Extracts resource to .Position in LIST object Note: resource may be (1) Resource(n) where n is an immediate integer or (2) a quoted string for the resource descriptor used in $RESOURCE. InsertItem (index, string$) Insert string$ at index position Existing data is not deleted but rather moved up. LoadFromFile (filename$) Loads filename$ into LIST at current position Any text file may be viewed and used as a LIST of items. Each text file line maps to a LIST item. After .LoadFromFile, the LIST .Position = 0, assuming sequential access with .ReadLine is likely. To use as LIST, LIST .Position = LIST .Length Note: SOCKET programmers can use this feature for line-based, text-only protocols, such has smtp or http. The incoming packet can be assigned to a LIST and lines processed as items. E.g., r$=MySock.Read(S,8000) 'ask for 8K and we will see what we get. 'get first line of http header (from server) or request (from client) h$=r$.Item(0) 'this illustrates the idea, but some network peers fail to use CRLF! LoadFromHandle + (mem_obj_handle, bytes) Read bytes of data from a memory object identified by its handle. If bytes is 0, .LoadFromHandle assumes the data is a text string and uses the LEN function to set bytes to load. If successful, .LoadFromHandle replaces object stream data with memory object data. MyList.LoadFromHandle mem_obj_handle, bytes LoadFromStream (stream) Loads stream into LIST starting at current .Position Parse (string$, delimiter$) Parse string$ using delimiter$ and add parsed items to LIST. Replace (index, string$) Replace index item with string$. MyList.Replace 3, "three" '0-based item 3 replaced with "three" As with .InsertItem, .DelItems and similar methods that rewrite a LIST, .Replace will be slow for larger LISTs, in which case use of a STRING array should be considered, where the above syntax would be simply MyArray(3)="three". SaveToFile (filename$) Save LIST to filename$ If filename$ exists, filename$ is overwritten. SaveToStream (stream) Save LIST to stream starting at stream .Position ########### Sorting Lists: ============= Please see SortList.inc in HotInclude. Strings as Lists: ================ Any dimensioned STRING may utilize any of the above properties and methods. E.g., s$.length is faster than LEN(s$). The former just reads the .Length property; the latter evaluates the length by looking for the first null byte as would be customary for text-only string data. + PentHouse registered version Copyright 2003-2007 James J Keene PhD Original Publication: Oct 9, 2003