When dealing with string maps, being able to easily load them from a file is a must. For example take language files for different local translations. The simplest, cleanest format would be CSV. The ideal data structure? — A hash map.
While trivial, this code will come in handy for many other things!
EnableExplicit
#CSV_QUOTE = "'"
#CSV_SEPARATOR = ","
Procedure IsEvenNumber(N)
ProcedureReturn ( 1 - 1 & N )
EndProcedure
Procedure IsOddNumber(N)
ProcedureReturn ( 1 & N )
EndProcedure
Procedure.s RemoveQuotes( String.s )
If Left(String, 1) = #CSV_QUOTE
String = Mid( String, 2 )
EndIf
If Right(String, 1) = #CSV_QUOTE
String = Left( String, Len(String) - 1 )
EndIf
ProcedureReturn String
EndProcedure
Procedure.i LoadStringMap( FileName.s, Map StringMap.s() )
; escaping of quotes is currently not supported
; if an uneven number of quotes is found on a line, the line is ignored.
Define.i fp = ReadFile( #PB_Any, FileName )
If IsFile(fp)
While Not Eof(fp)
Define.s line = Trim(ReadString( fp ))
If line
If CountString( line, #CSV_SEPARATOR ) => 1
Define.i quote_count = CountString( line, #CSV_QUOTE )
If IsEvenNumber( quote_count )
Define.s key = RemoveQuotes( StringField( line, 2, #CSV_QUOTE ) )
Define.s content = RemoveQuotes( StringField( line, 4, #CSV_QUOTE ) )
StringMap( key ) = content
EndIf
EndIf
EndIf
Wend
CloseFile(fp)
ProcedureReturn MapSize( StringMap() )
EndIf
EndProcedure
Example of data:
'Update', 'Actualizar' 'Databases', 'Bases de datos' 'Program', 'Programa' 'Options', 'Opciones' 'Export', 'Exportar'
Example of use:
NewMap spanish.s()
LoadStringMap( "locale/spanish.csv", spanish() )
ForEach spanish()
Debug MapKey(spanish())
Debug spanish()
Next
Couldn’t be easier!
Cheers.