findany
[1/7] from: louisaturk::eudoramail::com at: 23-Dec-2001 23:09
Rebol friends,
Why won't the following function work? Is there a better way to do this? Is
there a native rebol function for this that I have missed?
Louis
findany: func [
"Searches string x for any substring found in block ys."
x [string!] "string"
ys [block!] "block of substrings"
] [
foreach y ys [
if find x y [true break]
]
]
x: "There is a dog in the barn."
ys: ["cat" "pig" "dog" "skunk"]
if findany x ys [print "found"]
[2/7] from: louisaturk:eudoramail at: 23-Dec-2001 23:30
Ok, this works:
findany: func [
"Searches string x for any substring found in block y."
x [string!] "string"
ys [block!] "block of substrings"
] [
foreach y ys [
either find x y [z: true break] [z: false]
]
z
]
x: "There is a dog in the barn."
ys: ["cat" "pig" "dog" "skunk"]
if findany x ys [print "found"]
But is there a better way?
Louis
At 11:09 PM 12/23/2001 -0600, you wrote:
[3/7] from: louisaturk:eudoramail at: 23-Dec-2001 23:44
Whoops. There should be an s after the y in "Searches string x for any
substring found in block y." That is block ys not block y.
Louis
At 11:30 PM 12/23/2001 -0600, you wrote:
[4/7] from: brett:codeconscious at: 24-Dec-2001 16:52
Hi Louis,
Your function didn't do what you expected because BREAK does not return a
value by default. You
could use the /return refinement on BREAK though to return a TRUE.
So you change
if find x y [true break]
to
if find x y [break/return true]
An alternative is to use the RETURN keyword instead of break.
So you can use this instead:
if find x y [return true]
These two will work. In the case where the function does not find anything
it returns none - which is probably what
you want. For me I would probably add a "RETURN none" as the last line in
the function to explicitly make this happen
but this is a personal preference.
HTH!
Brett.
[5/7] from: carl:cybercraft at: 24-Dec-2001 18:51
On 24-Dec-01, Dr. Louis A. Turk wrote:
> Rebol friends,
> Why won't the following function work? Is there a better way to do
<<quoted lines omitted: 12>>
> ys: ["cat" "pig" "dog" "skunk"]
> if findany x ys [print "found"]
Instead of the [true break], use [return true].
However, it might be better to write it so what's returned is the
position in the string where the match is made, instead of just true.
ie...
findany: func [
"Searches string x for any substring found in block ys."
x [string!] "string"
ys [block!] "block of substrings"
/local pos
] [
foreach y ys [
if pos: find x y [return pos]
]
]
x: "There is a dog in the barn."
ys: ["cat" "pig" "dog" "skunk"]
print findany x ys
That will return the string at where the match was found, or a none if
no match was found.
Oh yes, and Merry Christmas too, Louis. (:
--
Carl Read
[6/7] from: louisaturk:eudoramail at: 24-Dec-2001 1:21
Brett and Carl,
Many thanks! I remember reading about return now. And I like the idea of
returning the position in the string instead of just true.
You guys have been helping me a lot lately. Thanks!
Louis
At 06:51 PM 12/24/2001 +1200, you wrote:
[7/7] from: greggirwin:mindspring at: 24-Dec-2001 10:44
Hi Louis,
<< And I like the idea of returning the position in the string instead of
just true. >>
Often times, if you're writing a routine that has a name similar to a
built-in function, or is intended to extend the functionality of a built-in
somehow, it's a good idea to model your behavior on the original (even if
you don't agree with its design :). It makes it much easier for people,
including yourself, to use your routine.
If you want different behavior, choose a distinct name. In your current
example, you might use a word like 'contains? or 'contains-any? which
naturally return a yes/no (boolean) answer.
--Gregg
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted