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::gmail 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.
--
--Alessandro
[5/19] from: moliad:gm:ail 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
Hi Tim,
>> 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:gm:ail 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.
--
--Alessandro
[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]
[1]
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
== "1.23.45.67.89.0"
>> separate/skip/at "1234567890" "." 2 0
== ".12.34.56.78.90"
>>
>> separate/at/skip "1234567890" ".-" 0 2
== ".1234-5678.90"
>> 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:gma:il 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:g:mail 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:g:mail 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::gmail 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:
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted