Re: Convert a string to title case
Posted: Tue Apr 01, 2025 10:41 am
@Seymour Clufley: Did you even read your code? Just do a search for 'StringField' in your code or even just search for 'String'.
http://www.purebasic.com
https://www.purebasic.fr/english/
@Seymour Clufley: Did you even read your code? Just do a search for 'StringField' in your code or even just search for 'String'.
I know I'm not the brighest cookie in the barrel here, but I swear i see the same exact line in borh sbippets"Demivec wrote: Tue Apr 01, 2025 10:41 am@Seymour Clufley: Did you even read your code? Just do a search for 'StringField' in your code or even just search for 'String'.
Word$ = StringField(String$, I, " ")
Of course it uses that earlier on, because I didn't change that bit. I was referring specifically to my method for checking words. It uses FindString.Demivec wrote: Tue Apr 01, 2025 10:41 am@Seymour Clufley: Did you even read your code? Just do a search for 'StringField' in your code or even just search for 'String'.
I think what he meant to say was: don't like how slow FindString is,...Quin wrote: Mon Mar 31, 2025 12:54 pm Very nice! Only reason I didn't do it this way is because I don't like how slow StringField is, but a linked list is probably overkill, I could probably make it a static array.
Yup Randy, you got it, my bad, I wrote that before having my coffee and know that both StringField and FindString are slow, so I got them confused in my state of uncaffeinated groggy morning blehnessRandy Walker wrote: Wed Apr 02, 2025 8:02 pm I think what he meant to say was: don't like how slow FindString is,...
That way his comment makes sense, but yeah I have to agree, a linked list is a bit of an overkill considering FindString works fine.
Code: Select all
EnableExplicit
Macro AddExcludedWord(_Word_)
AddMapElement(ExcludedWords$(),_Word_)
EndMacro
Procedure CapitalizeInplace(*inString)
Protected *String.character
Protected *Start, *End, exit,do,len
Protected *char.Unicode,tchar,bnext,word$
Static NewMap ExcludedWords$()
If MapSize(ExcludedWords$()) = 0
AddExcludedWord("a")
AddExcludedWord("an")
AddExcludedWord("the")
AddExcludedWord("and")
AddExcludedWord("but")
AddExcludedWord("or")
AddExcludedWord("for")
AddExcludedWord("nor")
AddExcludedWord("on")
AddExcludedWord("at")
AddExcludedWord("to")
AddExcludedWord("by")
AddExcludedWord("of")
AddExcludedWord("in")
AddExcludedWord("up")
AddExcludedWord("with")
AddExcludedWord("as")
EndIf
*String = *inString
*Start = *String
*End = *String
Repeat
If *String\c = 0
exit = #True
do = #True
*End = *String
Else
If *String\c = ' '
do = #True
*End = *String
EndIf
EndIf
If do
bnext=1
len = (*End - *Start) >> 1
If Len > 0
word$ = PeekS(*Start, len)
If Not FindMapElement(ExcludedWords$(),word$)
*char = *Start
While *char\u
If *Char\u = ' '
bnext= 1
*char+2
Break
ElseIf bnext
bnext = 0
If *char\u >=97 And *char\u <= 122
*char\u -32
EndIf
EndIf
*char+2
Wend
EndIf
EndIf
*Start = *String + SizeOf(character)
do = #False
EndIf
*String + SizeOf(character)
Until exit
EndProcedure
Procedure.b ListContainsString(List List$(), String$)
String$ = LCase(String$)
ForEach List$()
If LCase(List$()) = String$ : ProcedureReturn #True : EndIf
Next
ProcedureReturn #False
EndProcedure
; Converts a string to title case, respecting all the semantic rules that come along with that. For example, the at the very beginning of the string is capitalized, but anywhere else it isn't.
Procedure$ Capitalize(String$)
Protected.i i, Count
Protected Res$, Word$, FirstCharacter$, WordTail$
Static NewMap ExcludedWords$()
AddExcludedWord("a")
AddExcludedWord("an")
AddExcludedWord("the")
AddExcludedWord("and")
AddExcludedWord("but")
AddExcludedWord("or")
AddExcludedWord("for")
AddExcludedWord("nor")
AddExcludedWord("on")
AddExcludedWord("at")
AddExcludedWord("to")
AddExcludedWord("by")
AddExcludedWord("of")
AddExcludedWord("in")
AddExcludedWord("up")
AddExcludedWord("with")
AddExcludedWord("as")
Count = CountString(String$, " ") + 1
For i = 1 To Count
Word$ = StringField(String$, I, " ")
FirstCharacter$ = Left(Word$, 1)
WordTail$ = Right(Word$, Len(Word$) - 1)
If i = 1 Or Not FindMapElement(ExcludedWords$(), Word$) : FirstCharacter$ = UCase(FirstCharacter$) : EndIf
Word$ = FirstCharacter$ + WordTail$
Res$ + Word$ + " "
Next
Res$ = RTrim(Res$, " ")
ProcedureReturn Res$
EndProcedure
Global input.s = "this is a test of the function to see how it works with the two functions to see if they're the same or different"
Debug Capitalize(input)
CapitalizeInplace(@input)
Debug input
A rose by any other name. Isn't the map just another way to do a list? Looks the same to me, keeping in mind my middle name is Duhh".idle wrote: Wed Apr 02, 2025 10:16 pm a slightly modified version using a map instead of list and an in place version
A map only takes one look up, a list needs to lookup up more than one time until it finds the value or reaches the end of the list. Also if you do it in place by address of the string you don't need to take a copy of the string on the stack which means you have to walk the string to find its length to copy it. not a problem for short strings but long strings it becomes a problem.Randy Walker wrote: Thu Apr 03, 2025 12:41 amA rose by any other name. Isn't the map just another way to do a list? Looks the same to me, keeping in mind my middle name is Duhh".idle wrote: Wed Apr 02, 2025 10:16 pm a slightly modified version using a map instead of list and an in place version