Eliminar espacios intermedios en cadena

1,030 views
Skip to first unread message

Ultraton500

unread,
Nov 20, 2014, 4:23:05 PM11/20/14
to publice...@googlegroups.com
Buenas tardes, 
Tengo, en un cursor, un campo en donde el apellido y el nombre se encuentran separados por indefinidos espacios. Algo así:

Pérez             Daniel Ignasio
Gómez      Hugo Martín

y tengo que dejar solo uno.
Lo primero que se me ocurre es recorrer el cursor y pasar ese campo por unos cuantos STRTRAN() pero no me parece la manera correcta.

Alguien conoce alguna mejor manera para eliminar de manera mas sencilla los espacios que están de más?
Desde ya gracias.

Saludos,
Javier.

Miguel Canchas

unread,
Nov 20, 2014, 4:29:58 PM11/20/14
to publice...@googlegroups.com

Allan Raúl Acuña

unread,
Nov 20, 2014, 4:33:58 PM11/20/14
to publice...@googlegroups.com
Yo me hice esto:  ponlo en un PRG y le pasas la cadena a evaluar.



PARAMETERS cCadena
LOCAL nCount, lcTemp
lcTemp = ""
nCount = ALINES(laFrase, cCadena, SPACE(1))

FOR i = 1 TO nCount
    lcCaracter = laFrase[i]
    IF !EMPTY(laFrase[i])
       lcTemp = lcTemp + laFrase[i] + SPACE(1)
    ENDIF 
ENDFOR 

RETURN ALLTRIM(lcTemp)

Saludos cordiales.

Lic. Allan Raúl Acuña
Analista Programador
msn= allan...@hotmail.com
skype= NicEasySoft
            +(505) 8 999 8950
Managua, Nicaragua
Centroamérica



From: mcan...@ximesa.com
To: publice...@googlegroups.com
Subject: RE: [vfp] Eliminar espacios intermedios en cadena
Date: Thu, 20 Nov 2014 21:29:51 +0000

Víctor Hugo Espínola Domínguez

unread,
Nov 20, 2014, 5:01:36 PM11/20/14
to publice...@googlegroups.com
Hola Javier

Prueba este código:

lcTexto = "Hola    probando  eliminar más    de  un         espacio"
Do While Occurs(Space(2), lcTexto) > 0
    lcTexto = Strtran(lcTexto, Space(2), Space(1))
Enddo
Messagebox(lcTexto)

Saludos,
Víctor.
Lambaré - Paraguay.

Víctor Hugo Espínola Domínguez

unread,
Nov 20, 2014, 5:13:11 PM11/20/14
to publice...@googlegroups.com
Hola

Solución sin usar ciclo:

lcTexto = "Hola    probando  eliminar más    de   un         espacio"
lcTexto = Strtran(Strtran(lcTexto, Space(3), Space(1)), Space(2), Space(1))
Messagebox(lcTexto)

Saludos,
Víctor.
Lambaré - Paraguay.

ZeRoberto

unread,
Nov 20, 2014, 5:14:04 PM11/20/14
to publicesvfoxpro
? StrTran(lcCadena, "  ", " ")

Saludos

Luis Maria Guayan

unread,
Nov 20, 2014, 6:52:29 PM11/20/14
to publice...@googlegroups.com
Hay que acostumbrarse a buscar en el Blog !!!

-- Reducir los espacios entre palabras a solo un espacio --
http://comunidadvfp.blogspot.com/2004/04/reducir-los-espacios-entre-palabras.html

Luis María Guayán
Tucumán, Argentina
_____________________________
http://comunidadvfp.blogspot.com

El 20/11/2014 a las 18:23, Ultraton500 escibió:

Foxero

unread,
Nov 20, 2014, 10:40:20 PM11/20/14
to publice...@googlegroups.com
Hola

prueba esto...

x='Pérez             Daniel Ignasio'
y=GETWORDNUM(x,1)+' '+GETWORDNUM(x,2)+' '+GETWORDNUM(x,3)
? y

saludos
David

Ultraton500

unread,
Nov 21, 2014, 12:05:44 AM11/21/14
to publice...@googlegroups.com
Muchas gracias a todos por las diferentes soluciones. Era precisamente lo que estaba buscando.

Saludos cordiales,
Javier.

mapner

unread,
Nov 21, 2014, 3:39:28 AM11/21/14
to publice...@googlegroups.com
Hola,

Ahí va una solución sencilla, una función ITrim

Saludos

****************************************************************

MESSAGEBOX( ITrim("Hola       que        tal") )

**********
* ITrim
*
* elimina espacios intermedios en una cadena de caracteres
* ej: ITrim("Hola       que        tal") 
FUNCTION ITrim
LPARAMETERS cStr
LOCAL cRet, i

cRet = ''

FOR i=1 TO ALINES(aLineas,cStr,1+4,' ')
cRet = cRet + aLineas[i]+' '
ENDFOR

cRet = LEFT(cRet,LEN(cRet)-1)
RETURN cRet
ENDFUNC

****************************************************************

Marcelo Moreno

unread,
Nov 21, 2014, 4:05:01 AM11/21/14
to publice...@googlegroups.com
no es mas senillo
a="moreno raul marcelo"
a=strtran(a," ","")
? a
morenoraulmarcelo

El 21/11/14, mapner <mpis...@gmail.com> escribió:

Ultraton500

unread,
Nov 21, 2014, 8:59:53 AM11/21/14
to publice...@googlegroups.com
Gracias mapner, la voy a tener en cuenta.

Saludos,
Javier.

Ultraton500

unread,
Nov 21, 2014, 9:02:21 AM11/21/14
to publice...@googlegroups.com
Marcelo, lo que sugieres no deja ningún espacio entre palabras.

Saludos,
Javier.

Carlos Miguel FARIAS

unread,
Nov 21, 2014, 9:06:12 AM11/21/14
to Grupo Fox
Has un bucle while, condicionado para que se repita mientras encuentre dos caracteres en blanco dentro de la cadena y dentro del bucle aplicas lo que propone morenoraulmarcelo
Saludos: Miguel, La Pampa (RA)

Ariel D'Alfeo

unread,
Nov 21, 2014, 9:23:03 AM11/21/14
to publice...@googlegroups.com
Aporto mi opción :

FUNCTION reduceEspacios
LPARAMETERS lc as String
lcRetorno=''
FOR i=1 TO ATC(' ',lc)
    lcRetorno=lcRetorno+ GETWORDNUM(lc,i,' ') + ' '
NEXT
RETURN lcRetorno
ENDFUNC 

--
Ariel D'Alfeo
Córdoba, Argentina

Fidel Charny

unread,
Nov 21, 2014, 10:27:20 AM11/21/14
to publice...@googlegroups.com
Otra versión, ya que es viernes (y ya que usamos GETWORDNUM() )

PROCEDURE QuitMultiSpace
LPARAMETERS tcFrase
LOCAL lcString
lcSTring=""
FOR i=1 TO GETWORDCOUNT(lcFrase)
    lcString=lcString+IIF(EMPTY(lcString),""," ")+GETWORDNUM(tcFrase,i)
NEXT
RETURN lcString
ENDPROC

edgar suarez kummers

unread,
Nov 21, 2014, 11:47:37 AM11/21/14
to publice...@googlegroups.com
El word del windows 95 (creo) permitía en reemplazar dictarle dos espacios y reemplazar por un espacio. Haciendo esto repetitivo se veían textos muy bien elaborados en cuanto a espacios se refiere.

Luego vinieron los Moscardones y ya no se pudo hacer otra  vez eso.

Recemos todos porque:

Lo perfecto mata lo bueno.
Donde eramos ocho parió mi abuela.
Por ponerle María ramos le pusimos La Cagamos.



José Enrique Llopis

unread,
Nov 21, 2014, 12:27:52 PM11/21/14
to publice...@googlegroups.com

Efectivamente, esa funcionalidad se utilizaba antes, yo trabajé con la ofimática de UNISYS, el Ofis DSSP (de hecho desarrollé algún módulo en C ), y podías fácilmente dejar un texto con un espacio solo.

 

Pepe Llopis

 

 


Carlos Miguel FARIAS

unread,
Nov 21, 2014, 4:41:01 PM11/21/14
to Grupo Fox
DO WHILE "  "$cadena  && mientras encuentra dos blancos en la cadena
   cadena = STRTRAN(cadena, "  ", " ")  && lo reemplaza por uno
ENDDO  && lógica KISS

No funciona?, me parece muy simple

Saludos: Miguel, La Pampa (RA)

Joel de Jesus Rodriguez

unread,
Nov 21, 2014, 5:41:02 PM11/21/14
to publice...@googlegroups.com
para eso es el strtran()

lo que sugiere el amigo victor es mas simple y sencillo y se utilizan las funciones que estan escritas sin reinventar la rueda.

lcTexto = "Hola    probando  eliminar más    de   un         espacio"
lcTexto = STRTRAN(Strtran(lcTexto,Space(3),Space(1)),Space(2),Space(1))
Messagebox(lcTexto)


lo que se te ocurrio es correcto.

algunas de las soluciones que te proponen utilizan strtran() de todos modos, entonces donde esta lo mas sencillo?

Saludos,
Ultraton500.

Ultraton500

unread,
Nov 21, 2014, 9:22:55 PM11/21/14
to publice...@googlegroups.com
Así es, STRTRAN() es la función adecuada pero si no se la encierra en un DO WHILE la cantidad de niveles de anidamiento de STRTRAN() va a depender de la cantidad de espacios.

Las soluciones recibidas superaron mis expectativas por lo que les estoy muy agradecido. De haber contado con mas tiempo me hubiese gustado hacer pruebas de rendimiento con cada una.

Saludos y gracias a todos,
Javier.

Fidel Charny

unread,
Nov 22, 2014, 8:07:10 AM11/22/14
to publice...@googlegroups.com
La segunda versión que pasó Victor Hugo no necesita Do While y es la más eficiente. Luego le sigue la primer versión que pasó Victor Hugo (o la de Miguel, o la del blog que difieren solamente en "AT", "OCCURS" ó "$"). Luego las otras.
Por ejemplo, las que armamos con Getwordnum() debe ser la peor, porque no depende de la cantidad de veces que ocurre un Space(2) sino de la cantidad de palabras que tenga un texto.

Cuando se trate de un texto más complejo, se podría intentar algo como lo que sigue, para resolver el problema de la puntuación.
#DEFINE _TRIPLE_     "   "
#DEFINE _DOBLE_        "  "
#DEFINE _UNICO_     " "
#DEFINE _PTRIP_     "  ."
#DEFINE _PDOUB_     " ."
#DEFINE _PVALE_        "."
#DEFINE _PSIGUE_    ". "
#DEFINE _EOL_        CHR(13)+CHR(10)
LOCAL lnLines
, i,j,lcResulta,lcFrase
lcResulta
=""
LOCAL ARRAY laLines
(1)

TEXT TO
LcFrase NOSHOW PRETEXT 7
En  aquellos tiempos   la gente  solía   concurrir  a  matear  en  las plazas  .
Nada   había  para  temer .  recuerdo que dejábamos   nuestros     bolsos  sin  el  menor  cuidado  .
Muy  de   vez   en  cuando  alguno  se quejaba . . .
 eran  los   felices  a
ños   60 . Con  todos  sus problemas  eran  años  felices .
ENDTEXT

MESSAGEBOX
(lcFrase)

lnLines
=ALINES(laLines,lcFrase)
FOR i
=1 TO lnLines
    laLines
[i]=STRTRAN(STRTRAN(laLines[i], _TRIPLE_, _UNICO_), _DOBLE_ , _UNICO_ )
    laLines
[i]=Strtran(Strtran(laLines[i],_PTRIP_ ,_pVALE_ ), _PDOUB_ , _PVALE_ )
    IF OCCURS
(_PVALE_,laLines[i]) > 0
        lnPuntos
=ALINES(laPoint , laLines[i] ,16+1, _PVALE_ )
        laLines
[i]=""
        FOR j
=1 TO lnPuntos
            laLines
[i]=laLines[i]+ _UNICO_ + UPPER(LEFT(laPoint[j],1))+SUBSTR(laPoint[j],2)
        ENDFOR
    ENDIF
    lcREsulta
=lcREsulta+UPPER(LEFT(laLines[i],1))+SUBSTR(laLines[i],2) + _EOL_
NEXT
LcResulta=LEFT(lcResulta,LEN(lcREsulta)-LEN(_EOL_))
MESSAGEBOX
(lcResulta)

HernanCano

unread,
Nov 22, 2014, 1:08:49 PM11/22/14
to publice...@googlegroups.com
Joel:

Lo más sencillo es la alternativa que te da Miguel.

La que da Víctor no funciona, pues depende de qué tantos espacios  hay intermedio (amplíen hasta diez o más el número de espacios en cualq parte del texto y lo notarán).

La solución con GetWordNum() es interesante.

Ultraton500

unread,
Nov 22, 2014, 1:11:29 PM11/22/14
to publice...@googlegroups.com
No deja de ser interesante lo de la eficiencia para los casos en que, por ejemplo, se quiere importar una lista a la db teniendo en cuenta que se deberá ejecutar la rutina en varios campos y registro por registro.
También se debe tener en cuenta que además de los espacios podría haber tabulaciones y extender la funcionalidad de la rutina que reduce espacios para que también elimine las tabulaciones tendrá un impacto sobre el rendimiento.

Saludos,
Javier.

mapner

unread,
Nov 22, 2014, 4:35:47 PM11/22/14
to publice...@googlegroups.com
Acá les dejo una comparación de perfomance usando tres métodos.
En el ejemplo se usan un millón de blancos como separadores para que la comprativa tenga significancia...
En mi PC (i5, 8GB, W7 64bit) gana el primer método (STRTRAN - DO WHILE ... ENDDO)

Saludos

****************************************************************
* Testeando perfomance con diferentes métodos 

nSep = 1000000
cFrase = 'HOLA'+SPACE(nSep)+'que'+SPACE(nSep)+'tal'+SPACE(nSep)+'como'+SPACE(nSep)+'te'+space(nSep)+'va'

nSec = SECONDS()
xx = IWTrim(cFrase)  && Método de STRATRAN() - DO WHILE ... ENDDO
MESSAGEBOX( 'Tiempo IWTrim '+TRANSFORM(SECONDS()-nSec,'999999.9999') )

nSec = SECONDS()
xx = IRTrim(cFrase)  && Método de STRATRAN() - LLAMADO A FUNCION RECURSIVA
MESSAGEBOX( 'Tiempo IRTrim '+TRANSFORM(SECONDS()-nSec,'999999.9999') )

nSec = SECONDS()
xx = IATrim(cFrase) && Método de ALINES() - FOR ... ENDFOR
MESSAGEBOX( 'Tiempo IATrim '+TRANSFORM(SECONDS()-nSec,'999999.9999') )

**********
* ITrim
* Método ALINES() - FOR ... ENDFOR
* elimina espacios intermedios en una cadena de caracteres
* ej: ITrim("Hola       que        tal") 
FUNCTION IATrim
LPARAMETERS cStr
LOCAL cRet, i

cRet = ''

FOR i=1 TO ALINES(aLineas,cStr,1+4,' ')
cRet = cRet + aLineas[i]+' '
ENDFOR

cRet = LEFT(cRet,LEN(cRet)-1)
RETURN cRet
ENDFUNC

**********
* IWTrim
* Método STRTRAN() - DO WHILE ... ENDDO
* elimina espacios intermedios en una cadena de caracteres
* ej: ITrim("Hola       que        tal") 
FUNCTION IWTrim
LPARAMETERS cStr

DO WHILE "  "$cStr  &
   cStr = STRTRAN(cStr, "  ", " ")  
ENDDO  

RETURN cStr

ENDFUNC 

**********
* IRTrim
* Método STRTRAN() - FUNCION RECURSIVA
* elimina espacios intermedios en una cadena de caracteres
* ej: ITrim("Hola       que        tal") 
FUNCTION IRTrim
LPARAMETERS cStr

IF "  "$cStr  
cStr = STRTRAN(cStr, "  ", " ")  
cStr = IRTRIM(cStr)
ENDIF 

RETURN cStr

ENDFUNC 

Ultraton500

unread,
Nov 22, 2014, 6:21:53 PM11/22/14
to publice...@googlegroups.com
Excelente comparativa mapner!!

Saludos cordiales,
Javier.

HernanCano

unread,
Nov 22, 2014, 9:45:55 PM11/22/14
to publice...@googlegroups.com

Sí, mapner: muy bueno!!!
Hice las pruebas que propones y en mi portátil (core i3 2.3 GHz) la mejor eficiencia fue para la RECURSIVA.
Yo suponía que la más eficiente sería la de IWTrim (con ALINES) pues creía que le podría dar el espacio como separador, pero --como verán-- cualq suposición mía con ALINES estaba plenamente errada.

El primer LOG de resultados lo muestro aquí (y se adjunta):

IWTrim      0.8500    combinación "STRTRAN() - DO WHILE"
IRTrim      0.8200    combinación "STRTRAN() - Recursiva"
IATrim      1.0000    con ALINES

Pero quise dar oportunidad a las otras opciones y... ¡¡¡qué descubrimiento!!! Los resultados hablan por sí solos...

Las nuevas alternativas icluidas son: 
IGTrim1  &&reduceEspacios de Ariel
IGTrim2  &&QuitMultiSpace de Fidel
IPTrim   &&alternativa para puntuación de Fidel

Si bien la alternativa para puntuación (IPTrim) de Fidel es "eficiente", observamos que su objetivo es diferente (además de espacios, chequea puntos); también notemos que es muy elaborada: surgió como resultado de investigar cómo ajustar tanto espacios como puntos, lo que no es nuestro objetivo.

Personalmente he utilizado la alternativa que nos dio Víctor Hugo (la primera, pues la segunda falla en muchos casos).

¿No he hablado de las alternativas con GETWORDNUM?  Me quitaron el aliento!!!!! Vean el segundo LOG de resultados adjunto.

En los adjuntos mis acercamientos..............

PD: Disculpen no haber probado REDUCE de FoxTools.Fll, pues con GetWordNum y ATC tengo suficiente.

probar2.prg
log1.log
log2.log

Luis Maria Guayan

unread,
Nov 22, 2014, 10:39:52 PM11/22/14
to Comunidad Visual FoxPro en Español
A ver si prueban con FoxTool y se llevarán una GRAN sorpresa


SET LIBRARY TO (HOME() + "FoxTools.fll")
nSep = 1000000
cFrase = 'HOLA'+SPACE(nSep)+'que'+SPACE(nSep)+'tal'+SPACE(nSep)+'como'+SPACE(nSep)+'te'+space(nSep)+'va'
nSec = SECONDS()
? Reduce(cFrase)
MESSAGEBOX( 'Tiempo FoxTool '+TRANSFORM(SECONDS()-nSec,'999999.9999') )




 
Luis María Guayán
Tucumán, Argentina
_______________________________

mapner

unread,
Nov 22, 2014, 11:14:08 PM11/22/14
to publice...@googlegroups.com
Obvio ganador:  REDUCE de FoxTools.fll (buen aporte LMG!)
REDUCE de FoxTools.fll está escrito en lenguaje C, vs. el resto de las funciones propuestas en VFP... pero bien valió el ejercicio.

de paso dejo la función recursiva un tanto más sintética...

saludos

**********
* IRTrim
* Método STRTRAN() - FUNCION RECURSIVA
* elimina espacios intermedios en una cadena de caracteres
* ej: IRTrim("Hola       que        tal") 
FUNCTION IRTrim
LPARAMETERS cStr

RETURN IIF("  " $ cStr , IRTRIM( STRTRAN(cStr, "  ", " ")  ), cStr)  

ENDFUNC 

Víctor Hugo Espínola Domínguez

unread,
Nov 22, 2014, 11:19:22 PM11/22/14
to publice...@googlegroups.com
Siguen las sorpresas:

nSep = 1000000
lcTexto = 'HOLA'+Space(nSep)+'que'+Space(nSep)+'tal'+Space(nSep)+'como'+Space(nSep)+'te'+Space(nSep)+'va'
nSec = Seconds()
? UnSoloEspacio(lcTexto)
Messagebox( 'Tiempo triple StrTran '+Transform(Seconds()-nSec,'999999.9999') )

Return

Function UnSoloEspacio(tcTexto)

Do While At(Space(2), tcTexto) > 0
*Do While Space(2) $ tcTexto
    tcTexto = Strtran(tcTexto, Space(8), Space(1))
    tcTexto = Strtran(tcTexto, Space(4), Space(1))
    tcTexto = Strtran(tcTexto, Space(2), Space(1))
Enddo

Return  tcTexto

Víctor Hugo Espínola Domínguez

unread,
Nov 22, 2014, 11:26:42 PM11/22/14
to publice...@googlegroups.com
Otra más:

nSep = 1000000
lcTexto = 'HOLA'+Space(nSep)+'que'+Space(nSep)+'tal'+Space(nSep)+'como'+Space(nSep)+'te'+Space(nSep)+'va'
nSec = Seconds()
? UnSoloEspacio(lcTexto)
Messagebox( 'Tiempo quíntuple StrTran '+Transform(Seconds()-nSec,'999999.9999') )

Return

Function UnSoloEspacio(tcTexto)

*Do While At(Space(2), tcTexto) > 0

Do While Space(2) $ tcTexto
    tcTexto = Strtran(tcTexto, Space(32), Space(1))
    tcTexto = Strtran(tcTexto, Space(16), Space(1))

    tcTexto = Strtran(tcTexto, Space(8), Space(1))
    tcTexto = Strtran(tcTexto, Space(4), Space(1))
    tcTexto = Strtran(tcTexto, Space(2), Space(1))
Enddo

Return  tcTexto

HernanCano

unread,
Nov 23, 2014, 2:03:55 AM11/23/14
to publice...@googlegroups.com
Sí, Luis.
En mis pruebas la función Reduce dio resultados equiparables a IGTrim1 (GetWordNum y ATC), aunque Reduce dio 0.1000 en la diferencia de tiempos, y IGTrim1 dio 0.0900 .

Conclusiones:
((no se analizó la función IPTrim --la de mejoras para puntuación--))
1. Todas las funciones necesitan un ciclo para cumplir su comertido, excepto la recursiva y Reduce.

2. La recursiva es un poco más compleja ya que necesita de IIF (o de IF) y de STRTRAN para funcionar.

4. Los mejores tiempos los dieron IGTrim1, IGTrim2 (ambas utilizan GETWORDNUM --aunq con un ciclo--) y Reduce (aunque en distinto orden).

3. La función más simple es Reduce.... y con un tiempo equiparable al mejor encontrado.

Considero que el único inconveniente de Reduce es que debemos "instalar" FoxTools.Fll en nuestras app.... Pero aún así creo que Javier puede darse por bien servido que le hayamos mostrado eficiencia y así podrá decantarse por la solución que más aprecie.

------------------------------------------
Me siento complacido de haber podido aportar pruebas de eficiencia. Ojalá podamos hacerlo más a menudo.

HERNAN

HernanCano

unread,
Nov 23, 2014, 2:22:53 AM11/23/14
to publice...@googlegroups.com

Uy, Víctor.... Qué nota!!!  Y para más eficiencia sólo hay que incrementar el número de espacios... o un renglón más para más espacios.... uff!!! qué delicia de postre de efectividad!!!! 

Gracias, Víctor por compartir.

(( hasta tengo vergüenza de no haber incluido una alternativa así en mis pruebas ))

(( me parece que debe ser en múltiplos exponenciales de 16, perdón de 2 ¿cierto? ¿en cuánto puedo parar en 1024 --2**10-- o en 2048 --2**11--? ¿o en cuánto? ))

(( Has posteado los ejemplos pero unos con AT y otros con $. ¿Notaste preferencias con alguno de éstos dos? ))


El sábado, 22 de noviembre de 2014 23:26:42 UTC-5, Víctor Hugo escribió:
Otra más:

Function UnSoloEspacio(tcTexto)

*Do While At(Space(2), tcTexto) > 0
Do While Space(2) $ tcTexto
    tcTexto = Strtran(tcTexto, Space(32), Space(1))
    tcTexto = Strtran(tcTexto, Space(16), Space(1))
    tcTexto = Strtran(tcTexto, Space(08), Space(1))
    tcTexto = Strtran(tcTexto, Space(04), Space(1))
    tcTexto = Strtran(tcTexto, Space(02), Space(1))
Enddo

Return  tcTexto


Fidel Charny

unread,
Nov 23, 2014, 9:34:41 AM11/23/14
to publice...@googlegroups.com
Viendo la función recursiva de Mapner y el código ofrecido por Victor Hugo, hago un merge y obtengo lo siguiente:

* irTrim_b
* Versión modificada de irTrim() (mapner)
* Utilizando una formulación de Victor Hugo Espínola Dominguez
* Mezclador: Fidel
*
* PROCEDURE irTrim_B
#DEFINE _TRIPLE_     "   "
#DEFINE _DOBLE_        "  "
#DEFINE _UNICO_     " "


LPARAMETERS tcString
, tlRecursiveMode

tcString
=IIF(_DOBLE_ $ tcString,;
   
this.IrTrim_b(STRTRAN(STRTRAN(tcString, _TRIPLE_, _UNICO_), _DOBLE_ , _UNICO_ ), .t. ),;
            tcString
)

RETURN tcString

* ENDPROC

La ventaja de esta formulación (Victor Hugo) es que reduce a la mitad el número de iteraciones. Esto es importante ya que, por defecto, el número máximo de iteraciones es de 128 niveles de anidamiento (configuración de STACKSIZE). Para el caso en que se aplica, raramente supere los 10 niveles, pero al reducir las iteraciones mejora el rendimiento.
Se ha reemplazado la estructura IF por una función IIF() porque es un poco más veloz y de paso queda en una sola línea la llamada recursiva.

mapner

unread,
Nov 23, 2014, 1:43:19 PM11/23/14
to publice...@googlegroups.com
Bueno, siguen las sorpresas...

acá dejo dos nuevos métodos a puro VFP 

1) con RECURSIVIDAD    o    2) con DO WHILE...ENDDO 

Saludos

****************************************************************
* Testeando perfomance con 2 nuevos métodos 
* 1) con RECURSIVIDAD    o    2) con DO WHILE...ENDDO 

#define _1SP_ ' '
#define _2SP_ '  '
#define _LFCR_ CHR(13)+CHR(10)

nSep = 1000000

cStr = 'HOLA'+Space(nSep)+'que'+Space(nSep)+'tal'+Space(nSep)+'como'+Space(nSep)+'te'+Space(nSep)+'va'
nSec = Seconds()
cStr = IRTrimX(cStr)
Messagebox( 'Tiempo IRTrimX '+Transform(Seconds()-nSec,'999999.9999') +_LFCR_+_LFCR_+cSTR)

cStr = 'HOLA'+Space(nSep)+'que'+Space(nSep)+'tal'+Space(nSep)+'como'+Space(nSep)+'te'+Space(nSep)+'va'
nSec = Seconds()
cStr = IWTrimX(cStr)
Messagebox( 'Tiempo IWTrimX '+Transform(Seconds()-nSec,'999999.9999') +_LFCR_+_LFCR_+cSTR)

**********
* IRTrimX
* Método LTRIM - FUNCION RECURSIVA
* elimina espacios intermedios en una cadena de caracteres
* ej: IRTrimX("Hola       que        tal") 
FUNCTION IRTrimX
LPARAMETERS cStr
LOCAL nP

nP = AT(_2SP_,cStr)

RETURN IIF(nP=0, cStr, LEFT(cStr,nP-1)+IRTRIMX( _1SP_+LTRIM(SUBSTR(cStr,nP))))

ENDFUNC 

**********
* IWTrimX
* Método LTRIM - DO WHILE ... ENDDO
* elimina espacios intermedios en una cadena de caracteres
* ej: IWTrimX("Hola       que        tal") 
FUNCTION IWTrimX
LPARAMETERS cStr
LOCAL nP

nP = AT(_2SP_,cStr)

DO WHILE nP>0
cStr =  LEFT(cStr,nP-1)+_1SP_+LTRIM(SUBSTR(cStr,nP))
nP= AT(_2SP_,cStr)
ENDDO

RETURN cStr

ENDFUNC 

*************************************************************

Ultraton500

unread,
Nov 24, 2014, 10:58:16 AM11/24/14
to publice...@googlegroups.com
Cuando abrí este hilo esperaba un par de consejos para ver qué tan acertada era la solución que pensaba implementar pero no me imaginé tanta variedad de respuestas... un lujo!!
Realmente estoy muy agradecido por la cantidad y calidad de los aportes recibidos, cosa que no me sorprende para nada que así sea ya que este grupo es excepcional en ese aspecto y por eso me alegra mucho formar parte de él.
Siempre comento esto con personas que usan otras herramientas y esta me parece una buena oportunidad para destacarlo.

Saludos cordiales y nuevamente gracias a todos,
Javier.
Reply all
Reply to author
Forward
0 new messages