Re: piece function - there must be an easier/more elegant way !?
- Posted by martin.stachon at worldonline.cz May 16, 2001
- 360 views
This is a multi-part message in MIME format. ------=_NextPart_000_0013_01C0DE16.0C426AE0 charset="iso-8859-1" hi, i've written this code: --- CODE START constant NOT_FOUND =3D -1 function piece1(sequence s, integer delimiter, integer position) integer start,end_s,len_s,x len_s =3D length(s) start =3D 1 if not find(delimiter,s) then return NOT_FOUND else for i=3D1 to position-1 do start =3D find(delimiter,s[start..len_s]) + length(s[1..start]) if not start then return NOT_FOUND end if end for end_s =3D find(delimiter, s[start..len_s]) if not end_s then=20 end_s =3D len_s+1 x =3D 1 else=20 end_s +=3D length(s[1..start]) x =3D 2 end if if end_s =3D start then end_s =3D len_s+1 end if return s[start..end_s-x] end if end function --- CODE END another code, which is more elegant : --- CODE START function find_all(integer what, sequence where)=20 -- i think this routine should be built-in sequence result result =3D {} for i=3D1 to length(where) do if where[i] =3D what then result &=3D i end if end for return result end function function piece2(sequence s, integer delimiter, integer position) sequence x x =3D find_all(delimiter,s) if position =3D 1 then -- special case : first return s[1..x[1]-1] elsif position =3D length(x)+1 then -- special case : last return s[x[length(x)]+1..length(s)] else return s[x[position-1]+1..x[position]-1] end if end function --- CODE END My benchmarks shows that your routine is the fastest. I think there is no better way to do this. However, I am not a guru. (short time ago, i 'invented' a routine that was already in Eu. (I coded = it some way I gave it same name)) Regards, Martin ----- Original Message -----=20 From: <freeplay at mailandnews.com> To: EUforum <EUforum at topica.com> Sent: Monday, May 14, 2001 2:55 PM Subject: piece function - there must be an easier/more elegant way !? > Hello folks, >=20 > Attached is a short text file containing a function I've called piece. >=20 > It takes three arguments, a string sequence, a delimiter character and = an=20 > integer index. Using the delimter character it chops the string into = pieces=20 > and returns the one specified by the integer index. The integer index = begins=20 > at 1. >=20 > Hence: >=20 > sequence s > s =3D "andy:1:hello there::ok" >=20 > printf(1, "%s", {piece(s, ':', 1)}) >=20 > gives "andy" >=20 > printf(1, "%s", {piece(s, ':', 2)}) >=20 > gives "1" >=20 > printf(1, "%s", {piece(s, ':', 3)}) >=20 > gives "hello there" and >=20 > printf(1, "%s", {piece(s, ':', 4)}) >=20 > gives the null string "". >=20 > Asking for a piece out of range will also give "". >=20 > I think the way I've coded this is rather bad - there must be a more = elegant=20 > solution. Any offers? I've thought of strtok.e in the archives but = it might=20 > be a little overkill for my needs. >=20 > Note I needed to put the code in an attached text file as my web based = mailer=20 > messes up code indentation something rotton. >=20 > Best regards, >=20 > FP. ------=_NextPart_000_0013_01C0DE16.0C426AE0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META content=3D"text/html; charset=3Diso-8859-1" = http-equiv=3DContent-Type> <META content=3D"MSHTML 5.00.2614.3500" name=3DGENERATOR> <STYLE></STYLE> </HEAD> <BODY bgColor=3D#ffffff> <DIV><FONT face=3D"Arial CE" size=3D2>hi,</FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>i've written this = code:</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3DCourier size=3D2>--- CODE START</FONT></DIV> <DIV><FONT face=3DCourier size=3D2>constant NOT_FOUND =3D = -1</FONT></DIV> <DIV><FONT face=3DCourier size=3D2>function piece1(sequence s, integer = delimiter,=20 integer position)<BR> integer start,end_s,len_s,x<BR> len_s = =3D=20 length(s)<BR> start =3D 1<BR> if not find(delimiter,s)=20 then<BR> return NOT_FOUND<BR> else<BR> for = i=3D1 to=20 position-1 do<BR> start =3D = find(delimiter,s[start..len_s]) +=20 length(s[1..start])<BR> if not start then return = NOT_FOUND end=20 if<BR> end for<BR> end_s =3D find(delimiter,=20 s[start..len_s])<BR> if not end_s then = <BR> end_s =3D=20 len_s+1<BR> x =3D 1<BR> else=20 <BR> end_s +=3D = length(s[1..start])<BR> x =3D=20 2<BR> end if<BR> if end_s =3D start then end_s =3D = len_s+1 end=20 if<BR> return s[start..end_s-x]<BR> end if<BR>end=20 function</FONT></DIV> <DIV><FONT face=3DCourier size=3D2>--- CODE END</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3D"Arial CE" size=3D2>another code, which is more = elegant=20 :</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3D"Arial CE" size=3D2>--- CODE START</FONT></DIV> <DIV><FONT face=3DCourier size=3D2>function find_all(integer what, = sequence where)=20 </FONT></DIV> <DIV><FONT face=3DCourier size=3D2> -- i think this routine should=20 be built-in<BR> sequence result<BR> result =3D = {}<BR> for i=3D1=20 to length(where) do<BR> if where[i] =3D what then result = &=3D i end=20 if<BR> end for<BR> return result<BR>end function</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3DCourier size=3D2>function piece2(sequence s, integer = delimiter,=20 integer position)<BR> sequence x<BR> x =3D=20 find_all(delimiter,s)<BR> if position =3D 1 then -- special case :=20 first<BR> return s[1..x[1]-1]<BR> elsif position =3D = length(x)+1=20 then -- special case : last<BR> return=20 s[x[length(x)]+1..length(s)]<BR> else<BR> return=20 s[x[position-1]+1..x[position]-1]<BR> end if<BR>end = function</FONT></DIV> <DIV><FONT face=3DCourier size=3D2>--- CODE END</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3D"Arial CE" size=3D2>My benchmarks shows that your = routine is the=20 fastest.</FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>I think there is no better way to = do this.=20 However, I am not a guru.</FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>(short time ago, i 'invented' a = routine that=20 was already in Eu. (I coded it some way I gave it same = name))</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3D"Arial CE" size=3D2>Regards,</FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>Martin</FONT></DIV> <DIV> </DIV> <DIV><FONT face=3D"Arial CE" size=3D2>----- Original Message ----- = </FONT> <DIV><FONT face=3D"Arial CE" size=3D2>From: <<A=20 href=3D"mailto:freeplay at mailandnews.com">freeplay at mailandnews.com</A>>= </FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>To: EUforum <<A=20 href=3D"mailto:EUforum at topica.com">EUforum at topica.com</A>></FONT></DIV= > <DIV><FONT face=3D"Arial CE" size=3D2>Sent: Monday, May 14, 2001 2:55=20 PM</FONT></DIV> <DIV><FONT face=3D"Arial CE" size=3D2>Subject: piece function - there = must be an=20 easier/more elegant way !?</FONT></DIV></DIV> <DIV><FONT face=3D"Arial CE" size=3D2><BR>> Hello folks,<BR>> = <BR>>=20 Attached is a short text file containing a function I've called = piece.<BR>>=20 <BR>> It takes three arguments, a string sequence, a delimiter = character and=20 an <BR>> integer index. Using the delimter character it chops = the=20 string into pieces <BR>> and returns the one specified by the integer = index. The integer index begins <BR>> at 1.<BR>> <BR>>=20 Hence:<BR>> <BR>> sequence s<BR>> s =3D "andy:1:hello = there::ok"<BR>>=20 <BR>> printf(1, "%s", {piece(s, ':', 1)})<BR>> <BR>> gives=20 "andy"<BR>> <BR>> printf(1, "%s", {piece(s, ':', 2)})<BR>> = <BR>>=20 gives "1"<BR>> <BR>> printf(1, "%s", {piece(s, ':', 3)})<BR>> = <BR>>=20 gives "hello there" and<BR>> <BR>> printf(1, "%s", {piece(s, ':',=20 4)})<BR>> <BR>> gives the null string "".<BR>> <BR>> Asking = for a=20 piece out of range will also give "".<BR>> <BR>> I think the way = I've=20 coded this is rather bad - there must be a more elegant <BR>> = solution. =20 Any offers? I've thought of strtok.e in the archives but it might = <BR>>=20 be a little overkill for my needs.<BR>> <BR>> Note I needed to put = the=20 code in an attached text file as my web based mailer <BR>> messes up = code=20 indentation something rotton.<BR>> <BR>> Best regards,<BR>> = <BR>>=20 ------=_NextPart_000_0013_01C0DE16.0C426AE0--