joining strings
[1/5] from: semseddinm::bircom::com at: 27-Jul-2009 18:23
Hi,
What is the best way to join a block into a string with a separator?
I prefer not to use loop if it is possible.
b: ["a" "b" "1" "2"]
t: concat b "-"
t => "a-b-1-2"
[2/5] from: Christian::Ensel::gmx::de at: 27-Jul-2009 17:44
A bit rushed, but the following CONCAT seems to work.
concat: func [values [block!] sep [string! char!] /local string] [
string: copy ""
forall values [insert insert tail string sep first values]
remove/part string length? sep
]
>> concat [] ", "
== ""
>> concat [1] ", "
== "1"
>> concat [1 "2" <3>] ", "
== "1, 2, <3>"
>> concat [1 "2" <3> %4 #5] ", "
== "1, 2, <3>, 4, 5"
>> concat ["a" "b" "1" "2"] "-"
== "a-b-1-2"
>> concat ["a" "b" "1" "2"] ", "
== "a, b, 1, 2"
HTH,
Christian
-------- Original-Nachricht --------
> Von: "Åžemseddin Moldibi [ Bircom ]" <semseddinm-bircom.com>
> Betreff: [REBOL] joining strings
> What is the best way to join a block into a string with a separator?
> I prefer not to use loop if it is possible.
> b: ["a" "b" "1" "2"]
> t: concat b "-"
--
Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3 -
sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser
[3/5] from: dhsunanda:gmai:l at: 27-Jul-2009 16:57
> What is the best way to join a block into a string with a separator?
The best way may be a loop as it permits you to handle special cases as
they arise.
With your test example, this will work:
b: ["a" "b" "1" "2"]
replace/all form b " " "-"
== "a-b-1-2"
But that will fail if any of your strings have embedded spaces.
***
This works better with embedded spaces....
b: ["a z" " b" "1" "2"]
replace/all replace/all mold/only b { "} "-" {"} ""
== "a z- b-1-2"
....But it should not be hard to find test cases that break it -- eg if
your strings also have embedded quotes:
b: [{a z "} " b" "1" "2"]
Sunanda,
[4/5] from: gregg:pointillistic at: 27-Jul-2009 19:08
Hi Þemseddin,
ÞMB> What is the best way to join a block into a string with a separator?
ÞMB> I prefer not to use loop if it is possible.
ÞMB> b: ["a" "b" "1" "2"]
ÞMB> t: concat b "-"
ÞMB> == "a-b-1-2"
You got a couple replies already, but I'll add mine. In the past, some
of us have suggested that REJOIN would benefit from a /WITH
refinement, allowing you to specify an optional delimiting value.
Since REJOIN is a mezzanine, you could do that yourself.
I did that myself, but now I almost always use the following DELIMIT
function, combined with a REJOIN in front of it if need be. I've found
it to be more useful, with the skip refinement and ability to handle
strings directly.
I also use simple wrappers to make the intent clear, handle copying,
etc. e.g.
make-csv: func [block [block!]] [rejoin delimit copy block #","]
DELIMIT function:
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]
]
HTH!
-- Gregg
[5/5] from: sqlab:gmx at: 28-Jul-2009 8:38
Þemseddin Moldibi [ Bircom ] wrote:
> Hi,
> What is the best way to join a block into a string with a separator?
> I prefer not to use loop if it is possible.
>
> b: ["a" "b" "1" "2"]
> t: concat b "-"
>
> t => "a-b-1-2"
>
Hi Þemseddin,
normally I use a substitute of the original rejoin primarily proposend
by Andrew
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
]