[REBOL] Re: Removing Items
From: greggirwin:mindspring at: 3-Jul-2002 13:57
Hi Ken,
<< Simple question (hopefully). I'm reading from a very large quoted-comma
delimited text file and writing to a quoted-comma delimited text file.
I want to skip over the forty-first element and continue sending the
rest of the record to the outbound file. This would be repeated for
every record in the inbound file (over three hundred thousand). >>
REBOL's PARSE function is really good at splitting up data for you, but the
rest isn't *quite* so easy.
First, you can take the line of input (a string) and parse it into fields,
like so:
>> s: {a, b, "c, d, e", f, g}
== {a, b, "c, d, e", f, g}
>> parse s none
== ["a" "b" "c, d, e" "f" "g"]
Now you can remove field 41 very easily. I'll remove one item (at field
four) in my example here. Just replace 4 with 41 in your case.
>> head remove/part at parse s none 4 1
== ["a" "b" "c, d, e" "g"]
Now, it would be nice if REJOIN worked as a mirror of PARSE, but it doesn't,
as you can see below. It doesn't know about delimiters or fields that were
quoted in the original string.
>> rejoin head remove/part at parse s none 4 1
== "abc, d, eg"
To get around that, we can write a function to build a delimited string for
us without too much difficulty. I just coded this, without concern for
efficiency and very little testing. Caveat emptor.
make-dlm-str: func [
"Reduces and joins a block of values."
block [block!] "Values to reduce and join"
dlm [char! string!] "Delimiter to put between elements"
/local
mod-blk
][
mod-blk: make block! 2 * length? block
foreach item block [
append mod-blk reduce [
either find item dlm [mold item][item]
dlm
]
]
remove back tail mod-blk
rejoin mod-blk
]
Now we can do this, which looks OK to me:
>> make-dlm-str head remove/part at parse s none 4 1 ", "
== {a, b, "c, d, e", g}
This doesn't preserve the original formatting of course. If that's
important, or if you just want to tackle it a different way, you could use
PARSE in it's more powerful mode. E.g., as a starting point...
fld-sep: #","
valid-chars: complement charset ","
field: [
copy data [quoted-string | copy data some valid-chars] (print trim data)
[thru fld-sep | to end]
]
quoted-string: [{"} thru {"}]
rules: [some field to end]
>> s: {a, b, "c, d e", f, g}
>> parse s rules
(IANAPG - I Am Not A Parse Guru) so this quick example is likely flawed
somehow.
HTH!
--Gregg