Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Reverse comma-delimited string
Message
From
04/09/2019 11:43:04
 
 
To
04/09/2019 09:43:29
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
01670542
Message ID:
01670572
Views:
79
>>Just want to add that in my testing, ALINES() are much, much faster than the GETWORD*() functions. For a short string, it probably won't make much difference, but done repeatedly or for long strings, it'll be visible. (Mike, I know you know this; adding it for Rick.)
>
>I didn't exhaustively check this code. It may have bugs. I also altered Walter's algorithm slightly to provide a comma-space between each item. And on each item, I only process if a comma is found somewhere in the string.

Here's one that shows iteration for various length strings in 100-element increments, and in 10-element increments up to 50. ALINES() becomes considerably faster the larger the element list. The crossover seems to happen around 40 elements.
* 10 elements
0.040 ALINES() m.
0.040 ALINES()
0.023 GETWORDNUM() Rick
0.023 GETWORDNUM() Walter

* 20 elements
0.073 ALINES() m.
0.063 ALINES()
0.043 GETWORDNUM() Rick
0.050 GETWORDNUM() Walter

* 30 elements
0.108 ALINES() m.
0.095 ALINES()
0.072 GETWORDNUM() Rick
0.068 GETWORDNUM() Walter

* 40 elements
0.132 ALINES() m.
0.117 ALINES()
0.108 GETWORDNUM() Rick
0.105 GETWORDNUM() Walter

* 50 elements
0.153 ALINES() m.
0.150 ALINES()
0.175 GETWORDNUM() Rick
0.168 GETWORDNUM() Walter

* 100 elements:
0.424 ALINES() m.
0.403 ALINES()
0.493 GETWORDNUM() Rick
0.473 GETWORDNUM() Walter

* 200 elements
1.174 ALINES() m.
1.110 ALINES()
1.806 GETWORDNUM() Rick
1.819 GETWORDNUM() Walter

* 300 elements
2.233 ALINES() m.
2.242 ALINES()
3.849 GETWORDNUM() Rick
3.760 GETWORDNUM() Walter

*400 elements
3.606 ALINES() m.
3.581 ALINES()
6.625 GETWORDNUM() Rick
6.638 GETWORDNUM() Walter

* 500 elements
5.309 ALINES() m.
5.344 ALINES()
10.064 GETWORDNUM() Rick
10.022 GETWORDNUM() Walter


* A test to try out different REVERSE() algorithms, which take "a, b, c" and reverse it to "c, b, a"
* This test works with 100 element blocks
CLEAR
DIMENSION laAlinesM[5]
DIMENSION laAlines[5]
DIMENSION laGetWordNumR[5]
DIMENSION laGetWordNumW[5]

DIMENSION laUnique[500]
FOR lnI = 1 TO ALEN(laUnique, 1)
    laUnique[lnI] = SYS(2015)
NEXT

? ""
FOR lnPass = 1 TO 5

    * Build strings for this iteration
    lcReverse   = SPACE(0)
    lcForward   = SPACE(0)
    lnEnd       = lnPass * 100
    FOR lnI = 1 TO lnEnd
        lcForward = lcForward + laUnique[lnI] + ", "
        lcReverse = lcReverse + laUnique[lnEnd - lnI + 1] + ", "
    NEXT
    lcForward = RTRIM(RTRIM(lcForward), 1, ",")
    lcReverse = RTRIM(RTRIM(lcReverse), 1, ",")

    IF reverse_alines_mdot(lcForward) != lcReverse
        ? "reverse_alines_mdot() fails test on pass " + TRANSFORM(lnPass)
    ENDIF
    IF reverse_alines(lcForward) != lcReverse
        ? "reverse_alines() fails test on pass " + TRANSFORM(lnPass)
    ENDIF
    IF reverse_getwordnum_rick(lcForward) != lcReverse
        ? "reverse_getwordnum_rick() fails test on pass " + TRANSFORM(lnPass)
    ENDIF
    IF reverse_getwordnum_walter(lcForward) != lcReverse
        ? "reverse_getwordnum_walter() fails test on pass " + TRANSFORM(lnPass)
    ENDIF

    ? "**** Pass " + TRANSFORM(lnPass) + ", using " + TRANSFORM(lnPass * 100) + " elements"
    lnStart = SECONDS()
    FOR lnI = 1 TO 1000
        k = reverse_alines_mdot(lcForward)
    NEXT
    laAlinesM[lnPass] = SECONDS() - lnStart
    ? "ALINES() m.", SECONDS() - lnStart

    lnStart = SECONDS()
    FOR lnI = 1 TO 1000
        k = reverse_alines(lcForward)
    NEXT
    laAlines[lnPass] = SECONDS() - lnStart
    ? "ALINES()", SECONDS() - lnStart

    lnStart = SECONDS()
    FOR lnI = 1 TO 1000
        k = reverse_getwordnum_rick(lcForward)
    NEXT
    laGetWordNumR[lnPass] = SECONDS() - lnStart
    ? "GETWORDNUM() Rick", SECONDS() - lnStart

    lnStart = SECONDS()
    FOR lnI = 1 TO 1000
        k = reverse_getwordnum_walter(lcForward)
    NEXT
    laGetWordNumW[lnPass] = SECONDS() - lnStart
    ? "GETWORDNUM() Walter", SECONDS() - lnStart
    ? ""
NEXT

? "**** Averages"
? "ALINES() m.", show_average(@laAlinesM)
? "ALINES()", show_average(@laAlines)
? "GETWORDNUM() Rick", show_average(@laGetWordNumR)
? "GETWORDNUM() Walter", show_average(@laGetWordNumW)


FUNCTION show_average
LPARAMETERS taArray
EXTERNAL ARRAY taArray
LOCAL lnI, lnAvg
    lnAvg = 0
    FOR lnI = 1 TO ALEN(taArray, 1)
        lnAvg = lnAvg + taArray[lnI]
    NEXT
    RETURN ROUND(lnAvg / ALEN(taArray, 1), 2)


FUNCTION reverse_alines_mdot
LPARAMETERS tcText
LOCAL lnLines, lcText, x
LOCAL ARRAY laLines[1]
    IF "," $ tcText
        lnLines = ALINES(laLines,m.tcText,1,",")
        lcText  = laLines[m.lnLines]
        FOR x = lnLines-1 TO 1 STEP -1
            lcText = m.lcText + ", " + laLines[m.x]
        ENDFOR x
        RETURN m.lcText
    ENDIF
    RETURN tcText


FUNCTION reverse_alines
LPARAMETERS tcText
LOCAL lnLines, lcText, x
LOCAL ARRAY laLines[1]
    IF "," $ tcText
        lnLines = ALINES(laLines, tcText, 1, ",")
        lcText  = laLines[lnLines]
        FOR x = lnLines-1 TO 1 STEP -1
            lcText = lcText + ", " + laLines[x]
        ENDFOR x
        RETURN lcText
    ENDIF
    RETURN tcText


FUNCTION reverse_getwordnum_rick
LPARAMETERS tcString
LOCAL lnI, lcString
    IF "," $ tcString
        * Reverse comma-delimited items
        lcString = SPACE(0)
        FOR lnI = GETWORDCOUNT(tcString, ",") TO 1 STEP -1
            lcString = lcString + IIF(NOT EMPTY(lcString), ", ", SPACE(0)) + ALLTRIM(GETWORDNUM(tcString, lnI, ","))
        NEXT
    ELSE
        * Pass-thru
        lcString = tcString
    ENDIF
    RETURN lcString


FUNCTION reverse_getwordnum_walter
LPARAMETERS tcString
LOCAL lcString
    IF "," $ tcString
        * Reverse comma-delimited items
        lcString = ""
        FOR nT =  GETWORDCOUNT(tcString, ",") TO 1 STEP -1
            lcString = lcString + ALLTRIM(GETWORDNUM(tcString, nT, ",")) + ", "
        ENDFOR
        RETURN RTRIM(RTRIM(lcString), 1, ",")
    ELSE
        * Pass-thru
        lcString = tcString
    ENDIF
    RETURN lcString
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform