Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Best way to remove the trailing comma (or whatever) from a string? 4

Status
Not open for further replies.

GriffMG

Programmer
Mar 4, 2002
6,309
FR
Curiosity getting the better of me... and knowing I won't be roasted by the current community... I hope. B-)

Assuming we have assembled a string like "1234,123,198,678," what are your favourite ways to remove the trailing comma?

Code:
m.STRING = LEFT(m.STRING,LEN(m.STRING)-1)

Is ok if you are confident there is a trailing comma... Mike recently hinted that PadR() might be useful.



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
For anyone not familiar with Foxtools, you can find out more by perusing the Help file, FOXTOOLS.HLP, which is in the main VFP9 directory.

In fact, the only other function I have used recently is RGBComp(). Most of the other useful ones are now native to VFP.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Yes, and using this in production (within your EXE) of course means also providing foxtools.fll, which you're allowed to redistribute, too.
One SET LIBRARY and you have a slightly extended VFP language.

You won't get intellisense help when writing functions available through foxtools. That makes it a bit less pleasant than native functions. The necessary info for intellisense could be added to foxcode.dbf.

And now, if you're thinking this can be used to extend VFP language. Well, yes, but with functions only, an FLL can't define/declare new VFP commands, that's not foreseen in the structure of an FLL, especially the FoxInfo struture, that's described in the help, too:
This FoxInfo structre only can list functions and their parameterization.

Chriss
 
Of course REDUCE is no solution to the thread main title and question.

Code:
? REDUCE(",1234,123,198,678,",",")
output: 1234 123 198 678

If you might not know or care if your list string has a leading or a trailing commma or both, here's how ALLTRIM trims off commas from both ends and keeps the middle ones:

Code:
? ALLTRIM('1234,123,198,678,',',')
? ALLTRIM(',1234,123,198,678',',')
? ALLTRIM(',1234,123,198,678,',',')

All three variants result in: 1234,123,198,678. Well, and of course if the list already is correct, such an ALLTRIM does nothing, just like ALLTRIM on a string with neither leading nor trailing whitespace does anything.

Chriss
 
And here's a (drastical!) demonstration of how slow string concatenation is, to showcase how much importance is on the length of a list you build instad of what function exactly you use for the last step of removing a surplus comma:

Code:
Clear
Local s, t
s=''
t=Seconds()
t1=m.t
Do While Len(s)<16777384
   s=m.s+' '
   If Len(m.s)%10000=0
      ? Textmerge("<<Len(m.s))>>, average <<Round(Len(m.s)/(Seconds()-m.t),0)>> spaces per second, last 10000 spaces took <<Seconds()-m.t1>> seconds.")
      t1 = Seconds()
   Endif
EndDo

The obvious solution to get n spaces in a string is to use SPACE(n) instead of a while loop, but that's not the point. The point is to understand why adding just a single space to a string takes longer and longer, the longer the string is.

And I wouldn't have expected how high the performance degrades. It all plays a neglectible role from strings in the range of a few KB, but keep that in mind if you need to concatenate a lot of items.

Chriss
 
Using Regular Expression replacement:

Code:
LOCAL RegX AS VBScript.RegExp

m.RegX = CREATEOBJECT("VBScript.RegExp")

m.RegX.Global = .T.

m.RegX.Pattern = "([^\,\s]*)([\,\s]*)"

? TRIM(m.RegX.Replace("HELLO,,,WORLD,FROM,,,,TEK-TIPS", "$1 "))

(also, making sure there won't be duplicate spaces inside the string).
 
Wow, been an RTRIM() user since Fox 2.0 and never realized that. I have used ALLTRIM() mostly just to get rid of padded characters on either side for decades, but RTRIM() accepting more than one parameter... I guess I just never read the help file on that function. I assume LTRIM() allows the same thing.


Best Regards,
Scott
MSc ISM, MIET, MASHRAE, CDCAP, CDCP, CDCS, CDCE, CTDC, CTIA, ATS, ATD

"I try to be nice, but sometimes my mouth doesn't cooperate.
 
Hi Scott

All the 4 - TRIM, ALLTRIM, LTRIM and RTRIM accept more than 1 parameter - at least in VFP9. In addition you can specify them to be case-sensitive. Please have a look at the help file

hth

MarK
 
Griff said:
what are your favourite ways to remove the trailing comma?

FWIW my favorite and most used way is to avoid placing the comma at the end of the string in the first place.

In general, I start building the string with the first item (without a comma) followed by the rest of the items in the string, each PRECEDED by a comma.

The "rest" of the items might be from looping through an array (e.g. field names) or whatever.

Steve
 
Steve, that corresponds to my sample 5, totally valid. You can SKIP 1 and SCAN REST for starting with the second item in a cursor, or you loop for lnI=2 to alen(array) after you started with the first array element. Starting with the second element (or second row) of an array just isn't possible elegantly in a For each loop, but of course instead of starting with an empty string, you can start with the first item and then precede a comma before every further item.

It rarely makes sense to create a list, if there are no items, but whenever an empty list also can make sense (as optional parameter, for example), you should also cover that. For that corner case you need special caution about knowing you have at least 1 element, a normal SCAN or FOR EACH loop covers that case without special handling, and you end with what you started: An empty string. Because if you start a SCAN loop on EOF() you actually don't ever enter the loop body and execute it, the loop ends before it begins, likewise a FOR loop with a final value lower than the initial also does end before it begins.

Chriss
 
Wow, been an RTRIM() user since Fox 2.0 and never realized that

Don't feel bad about that, Scott. The second parameter was only added in VFP 9.0. Before that, the only thing you could trim was spaces.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,
Well THAT explains it! You know, when you spend 25+ years with a function, and you "know how it works", so easy to overlook the addition of some new capability in it. I mean, how often do you read the Help file for a function you "already know"? :)

That said, I don't know when I would need it. ><


Best Regards,
Scott
MSc ISM, MIET, MASHRAE, CDCAP, CDCP, CDCS, CDCE, CTDC, CTIA, ATS, ATD

"I try to be nice, but sometimes my mouth doesn't cooperate.
 
That's why we wrote the "What's New" books, to gather all the new stuff in one place. Even without those, the Help file has always had "What's New" sections to let you quickly learn what has changed.

Tamar
 
Scott24x7 said:
That said, I don't know when I would need it.

Do you realize I posted ALLTRIM with that additional parameter can be used as a universal solution to remove a surplus comma, no matter if it's a prefix or suffix comma. See my post from 29 Nov 22 21:10.

So actually it's usable as the answer to the main question of Griff. If that's of no use to you, then you may not ever create a comma separated items list or do it without surplus commas. Whatever, the way this additional parameter works is not only to change from whitespace to any other character, you can trim off any group of characters, and that can be useful for many kinds of operations, it's not always just whitespace that's unwanted.

Chriss
 
Tamar,
Yeah, and I read them when they came out, but I have big "gap years" between when I use VFP, and when I'm dormant. I went into developer retirement for 15 years, came back out, and picked VFP back up again around 2014. Since then I'm in and out. But in fairness, as I mentioned, the way I develop otherwise, I don't think I'd really ever use this extra parameter.
I do also watchin the auto help, where it tells you want parameters are used within the function as you type them, and I still never noticed this. I usually only use ALLTRIM anyway, anything else would have a test for length, and I'd likely use SUBSTR to get rid of unwanted characters.


Best Regards,
Scott
MSc ISM, MIET, MASHRAE, CDCAP, CDCP, CDCS, CDCE, CTDC, CTIA, ATS, ATD

"I try to be nice, but sometimes my mouth doesn't cooperate.
 
I think the question was to fix the string "HELLO,,,WORLD,FROM,,,,TEK-TIPS". Seems to me this can be done with a single line of code:

Code:
?CHRTRAN("HELLO,,,WORLD,FROM,,,,TEK-TIPS", ",", " ")

Which replaces all commas with a space, yielding:

HELLO WORLD FROM TEK-TIPS (the extra spaces are being removed by the HTML display...)

If the problem is to remove the extra spaces as well, thus leaving a single space separating each word, then VFP does not have a native function to perform that task. The use of the REDUCE function in the FoxTools FLL would be the answer in addition to the CHRTRAN function.

Code:
SET LIBRARY TO foxtools.fll ADDITIVE
?REDUCE(CHRTRAN("HELLO,,,WORLD,FROM,,,,TEK-TIPS", ",", " "), " ")


Greg
 
And just for the benefit of anyone not familiar with this, keep in mind that you only need to do [tt]SET LIBRARY[/tt] once during the session. Once you have established a library file (that is, an FLL), it will stay in force until the end of the session or until you override it with a different library. (The [tt]ADDITIVE[/tt] keyword is also supported.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top