Newbie Q: Search and delete from a Block
[1/24] from: kimm2::mcmaster::ca at: 3-Oct-2002 14:27
A simple question...
How do I go about searching and deleting from a block?
Ex.
["hello" "there" "this" "is" "an" "Example"]
I want to search for "this" and delete it to result with:
["hello" "there" "is" "an" "Example"]
Thanks!
Matt
[2/24] from: vdallaporta:wanadoo at: 3-Oct-2002 22:00
Maybe i am telling you bull shit as I am knew with rebol,
But for a novice like me, the simple way is to open your scrip with any kind
of text editor : VI , notpad etc
and then use the the replace/search fonction.
I feel Rebol consol is for evaluation, direct order but not for writing yr
programs
[3/24] from: pwoodward:cncdsl at: 3-Oct-2002 16:09
Hey -
assuming your series is done like so -
your_series: ["hello" "there" "this" "is" "an" "Example"]
you can remove found values from the series like so -
remove/part your_series find your_series "this"
- Porter
[4/24] from: greggirwin:mindspring at: 3-Oct-2002 14:13
Hi Matt,
<<
["hello" "there" "this" "is" "an" "Example"]
I want to search for "this" and delete it to result with:
["hello" "there" "is" "an" "Example"]
>>
>> head remove find ["hello" "there" "this" "is" "an" "Example"] "this"
== ["hello" "there" "is" "an" "Example"]
--Gregg
[5/24] from: vdallaporta:wanadoo at: 3-Oct-2002 22:06
I Just find it better
just type editor on you consol and suprise you have an ihm to open any file
IHM and do directly all what you want ....
[6/24] from: vdallaporta:wanadoo at: 3-Oct-2002 22:12
the correct way is
Editor %local
on your consol
[7/24] from: kimm2:mcmaster:ca at: 3-Oct-2002 16:35
Thanks Gregg! You're always a huge help. I knew there was a quick an
efficient way to get this done. :)
[8/24] from: al:bri:xtra at: 4-Oct-2002 8:51
Matt wrote:
> How do I go about searching and deleting from a block?
>
> Ex.
>
> ["hello" "there" "this" "is" "an" "Example"]
>
> I want to search for "this" and delete it to result with:
>
> ["hello" "there" "is" "an" "Example"]
>> help remove-each
USAGE:
REMOVE-EACH 'word data body
DESCRIPTION:
Removes a value from a series for each block that returns TRUE.
REMOVE-EACH is a native value.
ARGUMENTS:
word -- Word or block of words to set each time (will be local) (Type:
get-word word b
lock)
data -- The series to traverse (Type: series)
body -- Block to evaluate. Return TRUE to remove. (Type: block)
>> remove-each Item X: ["hello" "there" "this" "is" "an" "Example"] [Item this
]
== ["hello" "there" "is" "an" "Example"]
>> probe X
["hello" "there" "is" "an" "Example"]
== ["hello" "there" "is" "an" "Example"]
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[9/24] from: jason:cunliffe:verizon at: 3-Oct-2002 17:02
> How do I go about searching and deleting from a block?
>
> Ex.
> ["hello" "there" "this" "is" "an" "Example"]
>
> I want to search for "this" and delete it to result with:
> ["hello" "there" "is" "an" "Example"]
Hi Matt
It's a good question and great intro to Rebol.
There are probably 1001 cool way to do this in Rebol.
The magic words are 'find and 'remove.
Try this at the shell [rebol console]
>> thread: ["hello" "there" "this" "is" "an" "Example"]
== ["hello" "there" "this" "is" "an" "Example"]
>> remove find thread "this"
== ["is" "an" "Example"]
>> head thread
== ["hello" "there" "is" "an" "Example"]
Voila!
So what happened?
Let's start again...
>> thread: ["hello" "there" "this" "is" "an" "Example"]
== ["hello" "there" "this" "is" "an" "Example"]
>> find thread "this"
== ["this" "is" "an" "Example"]
See 'find has located the first instance of "this" in the block named 'thread'
>> index? find thread "this"
== 3
this
is the 3rd item in block
so where we now?
>> index? thread
== 1
we are at the beginning of the block
>> ? remove
USAGE:
REMOVE series /part range
DESCRIPTION:
Removes value(s) from a series and returns after the remove.
REMOVE is an action value.
ARGUMENTS:
series -- (Type: series port bitset none)
REFINEMENTS:
/part -- Removes to a given length or position.
range -- (Type: number series port)
[REBOL = Regular Expression Based Object Language]
Rebol lets us pass expressions to each other. That's why we can use:
find thread "this"
as an input argument to the 'remove action word
>> remove find thread "this"
== ["is" "an" "Example"]
Another way is to use 'at
>> ? at
USAGE:
AT series index
DESCRIPTION:
Returns the series at the specified index.
AT is an action value.
ARGUMENTS:
series -- (Type: series)
index -- Can be positive, negative, or zero. (Type: number)
Let's start once again
>> thread: ["hello" "there" "this" "is" "an" "Example"]
== ["hello" "there" "this" "is" "an" "Example"]
>> remove at thread 3
== ["is" "an" "Example"]
>> head thread
== ["hello" "there" "is" "an" "Example"]
We could also replace the 3 above with a richer expression. Once more..
== ["hello" "there" "is" "an" "Example"]
>> thread: ["hello" "there" "this" "is" "an" "Example"]
== ["hello" "there" "this" "is" "an" "Example"]
>> remove at thread index? find thread "this"
== ["is" "an" "Example"]
>> head thread
== ["hello" "there" "is" "an" "Example"]
Play around with this as much as possible at the beginning, and any time your
are not sure, just go back the basics. The first couple of chapters in Rebol
about series and blocks are full of magic, including some ideas which are quite
different from most other languages.
I do not recommend programming Rebol too much with compounded one-line phrases
like
remove at thread index? find thread "this"
except for fun and insight in a personal sessions at the shell.
Too many of them soon becomes hard/impossible to read. But it is very important
to develop a fluency in the basic idioms. I find it is it is better to cut
things up into many clean phrases with well-named words, then to pass those
along instead. When you then later those words into more versatile functions
your code will keep working and growing quickly.
I am sure others here have better explanations than mine.
Hope this helps anyway.
./Jason
[10/24] from: jason:cunliffe:verizon at: 3-Oct-2002 16:08
> Maybe i am telling you bull shit as I am knew with rebol,
> But for a novice like me, the simple way is to open your scrip with any kind
> of text editor : VI , notpad etc
> and then use the the replace/search fonction.
>
> I feel Rebol consol is for evaluation, direct order but not for writing yr
> programs
Vincent
No. You are about to discover one the great joys of Rebol - that is learning to
use the console for happy programming. Yes keep a txt editor open. But use the
rebol shell [console] as much as possible. It is your best friend. You build up
and test scripts and bits of them in the shell. Meanwhile cut and past between
the shell and your open text editor. This is great way to develop your permanent
scripts.
./Jason
[11/24] from: chalz:earthlink at: 4-Oct-2002 0:52
Err... Nope.
>> editor %local
** Script Error: editor has no value
** Near: editor %local
>>
I think you mean to say to do that in REBOL/View, once you "shell out" to
the text console.
That, and I'm pretty sure Matt was looking for a method to do this
dynamically, in code.
[12/24] from: vdallaporta:wanadoo at: 4-Oct-2002 8:29
hello,
You get the truth
When you exec with the consol editor %local the rebol editor is open but the
parameter expected is a valid name file...
Thus the editor is open so you can use it to search an open you rebol's
files...Then you can correct your file unless you'are not looking for
dynamic ways and this is to earlier for me...
Bye
[13/24] from: christophe:coussement:mil:be at: 8-Oct-2002 9:19
hi:
you've to work in two times:
1. find the word
2. remove it from the block
We can thus use the function "find" (to get a definition of it, type ? find in the console).
If found, "Find" will return the word followed by the following words, either none if
not found:
>> find ["hello" "there" "this" "is" "an" "Example"] "this"
== ["this" "is" "an" "Example"]
>>
We have then to remove the first element of this block, by using the function "remove":
>> remove ["this" "is" "an" "Example"]
== ["is" "an" "Example"]
>>
Because REBOL is the champion of the oneliners, we can write:
>> remove find ["hello" "there" "this" "is" "an" "Example"] "this"
== ["is" "an" "Example"]
>>
Ok, but now we cannot see what's before "is", and we should put it at the head of the
block... so we have to address it:
>> my-block: ["hello" "there" "this" "is" "an" "Example"]
== ["hello" "there" "this" "is" "an" "Example"]
>> remove find my-block "this"
== ["is" "an" "Example"]
>> my-block
== ["hello" "there" "is" "an" "Example"]
>>
Or put the pointer of the block to the head of it:
>> head remove find ["hello" "there" "this" "is" "an" "Example"] "this"
== ["hello" "there" "is" "an" "Example"]
>>
Hope this helps !
==christophe
[14/24] from: chris:ross-gill at: 8-Oct-2002 12:38
Hi,
> join word-split "hellotherethisisanexample" "this"
> == "hellothereisanexample"
>> rejoin word-split "hellotherethisisanexample" "this"
== "hellothereisanexample"
I'm sure there's a more elegant way to do it than my effort below, or one
that splits the string at all instances of the word...
- Chris
--
REBOL []
word-split: func [
string [string!] word [string!] /local first second
][
if not second: find string word [return reduce [string]]
first: copy/part string second
second: copy skip second length? word
return reduce [first second]
]
[15/24] from: chris:ross-gill at: 8-Oct-2002 13:05
Hi,
> >> rejoin word-split "hellotherethisisanexample" "this"
> == "hellothereisanexample"
Can do better, and not use preset words (d'oh!)...
- Chris
--
REBOL []
word-split: func [
string [string!] word [string!] /local txt blk
][
blk: copy []
while [txt: find string word][
append blk copy/part string txt
string: skip txt length? word
]
append blk string return blk
]
[16/24] from: dockimbel:free at: 8-Oct-2002 22:21
Hi Chris,
Christopher Ross-Gill wrote:
> Hi,
> > join word-split "hellotherethisisanexample" "this"
<<quoted lines omitted: 14>>
> return reduce [first second]
> ]
I would do it like that :
word-split: func [text [string!] value [string!] /local fst snd][
parse text [to value s: (fst: copy/part txt s) value s: (snd: copy
s)]
reduce [fst snd]
]
or
word-split: func [text [string!] value [string!] /local pos][
reduce [copy/part text pos: find text value copy skip pos length?
value]
]
which would make my java-addicted friends say: "REBOL has a really bad
syntax" ! ;-)
-DocKimbel
[17/24] from: rotenca:telvia:it at: 9-Oct-2002 2:05
Hi,
> I would do it like that :
>
> word-split: func [text [string!] value [string!] /local fst snd][
> parse text [to value s: (fst: copy/part txt s) value s: (snd: copy
> s)]
> reduce [fst snd]
> ]
and i:
word-split: func [s w][parse/all replace s w #{00} "^(0)"]
0 not in string :-(
---
Ciao
Romano
[18/24] from: dockimbel:free at: 9-Oct-2002 15:37
Hi Romano,
En réponse à Romano Paolo Tenca <[rotenca--telvia--it]>:
> Hi,
> > I would do it like that :
<<quoted lines omitted: 8>>
> word-split: func [s w][parse/all replace s w #{00} "^(0)"]
> 0 not in string :-(
Very smart and elegant solution! :-)
(I usually do not use 'replace mezzanine in my code unless i don't care about
speed)
-DocKimbel.
[19/24] from: rotenca:telvia:it at: 9-Oct-2002 23:25
Hi Doc,
> (I usually do not use 'replace mezzanine in my code unless i don't care
about
> speed)
Time to try to speed up replace?
This is my first try (+ 100% in my system) . Anything better?
(I'm using more and more parse and i usually reach more fast loop (+50% -
+100%),
more compact and more readable code.)
replace: func [
{Replaces the search value with the replace value within the target
series. Changed by ana}
target [series!] "Series that is being modified."
search "Value to be replaced."
replace "Value to replace with."
/all "Replace all occurrences."
/case "Case-sensitive replacement."
/local start end rule
][
rule: [to search start: search end: opt (end: change/part start replace
end) :end]
if all [any-string? target any [not any-string? :search tag? :search]]
[search: form :search]
if all [rule: reduce ['some rule]]
either case [parse/all/case target rule][parse/all target rule]
target
]
---
Ciao
Romano
[20/24] from: g:santilli:tiscalinet:it at: 10-Oct-2002 0:41
Hi Romano,
On Wednesday, October 9, 2002, 11:25:46 PM, you wrote:
RPT> if all [any-string? target any [not any-string? :search tag? :search]]
RPT> [search: form :search]
Does this work? You have 'ALL as a local word...
BTW, for a long string copying to a new string will probably be
faster than changing the original (unless you're not moving data
around at all, i.e. when SEARCH has the same length as
REPLACE...).
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[21/24] from: rotenca:telvia:it at: 10-Oct-2002 1:24
Hi Gabriele,
> RPT> if all [any-string? target any [not any-string? :search tag?
:search]]
> RPT> [search: form :search]
>
> Does this work? You have 'ALL as a local word...
Does not work. I forgot system/words/, i try also to remove the if (but i'm
not sure that the efinal evaluation of the search value does not make fail the
block of all in some cases)
system/words/all [any-string? target any [not any-string? :search tag?
:search] search: form :search]
> BTW, for a long string copying to a new string will probably be
> faster than changing the original (unless you're not moving data
> around at all, i.e. when SEARCH has the same length as
> REPLACE...).
I fear that memory can become a problem with very long series! and additional
test on the lenghts could slow the function, i think.
----- new version ----
replace: func [
{Replaces the search value with the replace value within the target
series. Changed by ana}
target [series!] "Series that is being modified."
search "Value to be replaced."
replace "Value to replace with."
/all "Replace all occurrences."
/case "Case-sensitive replacement."
/local start end rule
][
rule: [to search start: search end: opt (end: change/part start replace
end) :end]
system/words/all [any-string? target any [not any-string? :search tag?
:search] search: form :search]
if all [rule: reduce ['some rule]]
either case [parse/all/case target rule][parse/all target rule]
target
]
---
Ciao
Romano
[22/24] from: rotenca:telvia:it at: 10-Oct-2002 16:34
Hi Gabriele,
> RPT> if all [any-string? target any [not any-string? :search tag?
:search]]
> RPT> [search: form :search]
Rethinking to this, now It seems to me that this expression is unuseful in the
parse version, it is used in the RT version only to calculate the string
length of search (in the following missing line).
But using a formed 'search should speed up things with many matched cases,
else the parse rule must form the search value at any iteration.
BTW, that tag? is interesting for me: formed tag string are an exception in
the any-string group.
>BTW, for a long string copying to a new string will probably be
>faster than changing the original (unless you're not moving data
>around at all, i.e. when SEARCH has the same length as
>REPLACE...).
now i have made tests with long strings (> 10000 chars) and many matched
searches and i do not see so any differences between while and parse. I think
that all the time, in such cases, is consumed by the change/part command.
Perhaps one could add to replace a /copy refinement.
---
Ciao
Romano
[23/24] from: g:santilli:tiscalinet:it at: 10-Oct-2002 20:18
Hi Romano,
On Thursday, October 10, 2002, 4:34:35 PM, you wrote:
RPT> BTW, that tag? is interesting for me: formed tag string are an exception in
RPT> the any-string group.
IIRC in older versions if you inserted a tag into a string you
didn't get the tag delimiters (only the content of the tag was
inserted). So maybe that's a leftover from older versions.
RPT> now i have made tests with long strings (> 10000 chars) and many matched
RPT> searches and i do not see so any differences between while and parse. I think
RPT> that all the time, in such cases, is consumed by the change/part command.
Indeed.
RPT> Perhaps one could add to replace a /copy refinement.
Or create a new string, and the use it to change the old one. If
there are a lot of occurrences it could be a lot faster...
Anyway, a general and fast version is probably not very easy to
write...
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[24/24] from: rotenca:telvia:it at: 10-Oct-2002 21:50
Hi Gabriele,
> RPT> BTW, that tag? is interesting for me: formed tag string are an
exception in
> RPT> the any-string group.
>
> IIRC in older versions if you inserted a tag into a string you
> didn't get the tag delimiters (only the content of the tag was
> inserted). So maybe that's a leftover from older versions.
It is a "must" in the actual version: the length? of tag exclude "<>" chars,
but form do not exclude them. Is the only exception in the any-string domain:
length? #a ;== 1
length? form #a;== 1
length? %a;== 1
length? form %a;== 1
length? <a>;== 1
length? form <a>;== 3
Replace must know the length of the formed version.
And: yes writing an full optimized version of replace is not a trivial task.
---
Ciao
Romano
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted