How to compose a string with a specific separator
[1/19] from: ale870::gmail::com at: 9-Jul-2007 17:42
Hi, I'm not new in this list, but I left Rebol for some time, for some problems. Now I'm back again :-) And... I have a question :-( I need to create a string to be inserted in a log file. Such string should be composed using ",". Now I do this: log-output: rejoin [now "," username "," ERROR_MESSAGE] My question is: is there any rebol command to join some data, but selecting a custom separator (e.g.: "," or "/" , etc...)? (else, I will proceed as in the example above :-) ) Thank you for your help! -- --Alessandro
[2/19] from: gschwarz::netconnect::com::au at: 11-Jul-2007 17:28
Welome back :-) You could use either something = something-else [log-output: rejoin [now "," username "," ERROR_MESSAGE]][log-output: rejoin [now "/" username "/" ERROR_MESSAGE]] Regards, Greg
[3/19] from: sqlab:gmx at: 11-Jul-2007 12:54
hi Alessandro, long ago Andrew came up with this function rejoin: func [ "Reduces and joins a block of values." block [block!] "Values to reduce and join" /with string [ string! ] ][ if empty? block: reduce block [return block] if with [ block: next block forskip block 2 [ insert block string ] ] block: head block append either series? first block [copy first block] [ form first block] next block ] This is one of the few functions, not delivered by RT, I still use from time to time. By the way, does any one know if Andrew recovered? Alessandro Manotti wrote:
[4/19] from: ale870:gm:ail at: 11-Jul-2007 13:56
Yes, I know (see my example :-) ) that method. I was looking for an alternative way (just for curiosity, or to create a shorter code). Thank you! On 7/11/07, Greg Schwarz <gschwarz-netconnect.com.au> wrote:
> Welome back :-) > You could use
<<quoted lines omitted: 57>>> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
[5/19] from: moliad:g:mail at: 11-Jul-2007 11:48
tought I'd take a 30 sec break and solve this using parse :-) a: [1 2 3] parse a [any [blk: skip (unless empty? next blk [insert next blk ","]) skip ] ] == [ 1 "," 2 "," 3" ] -MAx On 7/11/07, Alessandro Manotti <ale870-gmail.com> wrote:
[6/19] from: gregg:pointillistic at: 11-Jul-2007 11:26
[DELIMIT REJOIN] How to compose a string with a specific separator
Hi Alessandro, Others responded already, so I'll just contribute a general purpose func to the conversation. To everyone on the list: How often do you use/need this functionality (building delimited strings)? -- Gregg delimit: func [ "Insert a delimiter between series values." series [series!] "Series to delimit. Will be modified." value "The delimiter to insert between items." /skip ;<-- be sure to use system/words/skip in this func size [integer!] "The number of items between delimiters. Default is 1." ][ ; By default, delimiters go between each item. ; MAX catches zero and negative sizes. size: max 1 any [size 1] ; If we aren't going to insert any delimiters, just return the series. ; This check means FORSKIP should always give us a series result, ; rather than NONE, so we can safely inline HEAD with it. if size + 1 > length? series [return series] ; We don't want a delimiter at the beginning. series: system/words/skip series size ; Use size+n because we're inserting a delimiter on each pass, ; and need to skip over that as well. If we're inserting a ; series into a string, we have to skip the length of that ; series. i.e. the delimiter value is more than a single item ; we need to skip. size: size + any [ all [list? series 0] ; lists behave differently; no need to skip dlm. all [any-string? series series? value length? value] all [any-string? series length? form value] 1 ] head forskip series size [insert/only series value] ] ; >> make-csv: func [block] [rejoin delimit copy block #","] ; >> make-csv ['name 'rank 'serial-number] ; == "name,rank,serial-number" ; ; >> make-parse-OR: func [block] [delimit copy block '|] ; >> make-parse-OR [yes no maybe] ; == [yes | no | maybe] ; ; >> make-name-val-lines: func [block] [form delimit/skip copy block newline 2] ; >> print make-name-val-lines ["name:" 'Gregg "rank:" 'private "serial-number:" #0000] ; name: Gregg ; rank: private ; serial-number: 0000
[7/19] from: jblake::arsenaldigital::com at: 11-Jul-2007 14:42
I had to use one to generate a tab delimited file from postgres info. I haven't written too many scripts but so far I'd say about 15% of them needed to use one. John
[8/19] from: tim-johnsons::web::com at: 11-Jul-2007 16:58
Re: How to compose a string with a specific separator
On Wednesday 11 July 2007, sqlab wrote:
> This is one of the few functions, not delivered by RT, I still use from > time to time. > > By the way, does any one know if Andrew recovered?
Recovered from what? The last time I heard from him, he indicated that he was no longer able to work with code (I'm paraphrasing him). I assumed he was not well, but didn't know if the situation was permanent or not. Just curious. Tim
[9/19] from: gregg:pointillistic at: 12-Jul-2007 10:05
>> By the way, does any one know if Andrew recovered?
TJ> Recovered from what? TJ> The last time I heard from him, he indicated that he was no longer TJ> able to work with code (I'm paraphrasing him). I assumed he was TJ> not well, but didn't know if the situation was permanent or not. TJ> Just curious. I don't remember his exact health issue, but I haven't seen him around in a very long time. It doesn't look like there are any recent changes to his old site at http://www.rebol.it/Valley/Personal/index.html. -- Gregg
[10/19] from: carlos::lorenz::gmail::com at: 12-Jul-2007 14:07
Hi ppl a: [1 2 3]
> parse a [any [blk: skip (unless empty? next blk [insert next blk ","]) > skip > ] ] > > == [ 1 "," 2 "," 3" ] >
Whenever I read things like that I feel like I miss a lot about the power of REBOL parse dialect. IŽll leave a suggestion to the gurus on parsing: please write some "parsing for dummies" tutorial. It would be of great help! -- Carlos Lorenz www.revistaeletronica.com.br Unidade Lorenz Ltda (11) 4034 1971
[11/19] from: Tom:Conlin:g:mail at: 12-Jul-2007 10:21
Carlos Lorenz wrote:
> Hi ppl > a: [1 2 3]
<<quoted lines omitted: 8>>> I=B4ll leave a suggestion to the gurus on parsing: please write some "parsing > for dummies" tutorial. It would be of great help!
slightly shorter version of Max's parse a [any[skip here: (all[not tail? here insert here ","])skip]]
[12/19] from: ale870:g:mail at: 12-Jul-2007 22:36
Hello, I created this small function: composeBlock.
>> composeBlock: func [argDivider [string!] argData [block!] /local newBlock
][newBlock:  foreach i argData [ app end newBlock reduce [argDivider i] ] return copy next newBlock ]
>> >> composeBlock "," [1 2 3 4 5]
== [1 "," 2 "," 3 "," 4 "," 5]
On 7/12/07, Tom <Tom.Conlin-gmail.com> wrote:
> Carlos Lorenz wrote: > > Hi ppl
<<quoted lines omitted: 22>>> To unsubscribe from the list, just send an email to > lists at rebol.com with unsubscribe as the subject.
[13/19] from: pwawood::gmail::com at: 13-Jul-2007 7:29
Hi Carlos I found Brett Handley's parse tutorial a great help - http://www.codeconscious.com/rebol/parse-tutorial.html Peter On Friday, July 13, 2007, at 01:07 am, Carlos Lorenz wrote:
> Hi ppl > > a: [1 2 3] >> >> parse a [any [blk: skip (unless empty? next blk [insert next blk ,
[14/19] from: moliad::gmail::com at: 12-Jul-2007 23:25
hi list, here a separation (series division) func on steroids, which uses parse and some smart indexing . it supports, /SKIP /AT /ONLY options directly as refinements and the separator, if its a series, will be cycled at each separation (unless you use the /only refinement:) SEPARATE: func [ "separates the serie into a serie of the same type using a specified separator and many flexible options" serie [series!] "series you wish to separate" separator "if this is a series, it cycles each item at each separation." /only "if separator is a series, insert it as-is at each separation." /skip skip-count /at offset "note, use 0 to insert at head of (before) series!" /local here ][ skip-count: (any [skip-count 1]) - 1 + either only[length? separator]  if at [ serie: system/words/at serie offset ; add an item in serie so algorythm adds something after it, instead of after first char if offset = 0 [ serie: head insert serie "#" ] ] parse/all serie [any [ here: skip ( unless empty? next here [ either all [ series? separator not only] [ insert next here any [ ; cycle through separator all [not empty? separator first separator ] first separator: head separator ] separator: system/words/skip separator 1 ; error free way to go to next item ][ insert next here separator ] ] ) skip-count skip ] ] if offset = 0 [ ; remove the first item of series, which we added remove serie ] head serie ]
>> separate/skip "1234567890" "." 2
>> separate/skip/at "1234567890" "." 2 0
>> >> separate/at/skip "1234567890" ".-" 0 2
>> separate/at/skip/only "1234567890" ".-" 0 4
== ".-1234.-5678.-90" and a cool advanced example :-)
>> separate/at/skip "123112321233" ": " 2 2
== "12:31 12:32 12:33" also usefull for this:
>> do separate [12 34 23 12] '+
== 81 HAVE FUN ! :-) -MAx On 7/12/07, Alessandro Manotti <ale870-gmail.com> wrote:
[15/19] from: lmecir::mbox::vol::cz at: 13-Jul-2007 17:46
Carlos Lorenz napsal(a):
> Hi ppl > a: [1 2 3]
<<quoted lines omitted: 9>>> I=B4ll leave a suggestion to the gurus on parsing: please write some "parsing > for dummies" tutorial. It would be of great help!
The above code is O(n ** 2) slow. A reasonable algorithm should be much faster. Example: parse a [(result: copy ) any [copy element skip (append result element append result ",")] (clear back tail result)] -L
[16/19] from: moliad:gm:ail at: 13-Jul-2007 12:18
before I get flamed... the following is a <joke> Carlos... who ever said, parse IS for dummies ? ;-) -MAx On 7/12/07, Carlos Lorenz <carlos.lorenz-gmail.com> wrote:
[17/19] from: moliad:gmai:l at: 13-Jul-2007 12:21
Lad, I did not even try to look at the speed and optimicity of the algo, I left that for you ;-) The most optimal solution is often to convert the series to a list (cause it has a very low hit on repeated inserts) and then convert back... on long series, this has often improved my benchmarks by a few order of magnitudes. -MAx On 7/13/07, Ladislav Mecir <lmecir-mbox.vol.cz> wrote:
[18/19] from: santilli:gabriele::gmail at: 13-Jul-2007 18:27
2007/7/13, Maxim Olivier-Adlhoch <moliad-gmail.com>:
> The most optimal solution is often to convert the series to a list (cause it > has a very low hit on repeated inserts) and then convert back... on long > series, this has often improved my benchmarks by a few order of magnitudes.
Actually, that means copying twice, which is much slower than Ladislav's way. Of course, for large blocks you have to preallocate the destination block. Eg. instead of using (result: copy ) as in Ladislav's code you'd use (result: make block! 2 * length? a). HTH, Gabriele.
[19/19] from: moliad:gmai:l at: 13-Jul-2007 12:48
yes for this simple problem Lad's method is optimal... but when doing dialecting which builds series data on the fly.... using lists is very optimal. converting to blocks or strings, although a hit in itself, is done in binary by rebol and is still pretty fast in my tests so far. -MAx PS: I am slowly comming back to using my computer (and rebol)... It was offline for 3 weeks due to stuff I had to do in my personal life... it actually was in a box, with inet access not possible on top of it. On 7/13/07, Gabriele Santilli <santilli.gabriele-gmail.com> wrote:
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted