2

Using Rebol how do I split this string into characters (without using a c-like approach with loops)? I'm using version 2.7.8.2.5 which does not have the split method.

str: "Today is Monday"

I want to split the above into:

[ 'T' 'o' 'd' 'a' 'y' ' ' 'i' 's' ' ' 'M' 'o' 'n' 'd' 'a' 'y']

Parse method seems to only split a sentence into constituent words.

Thank you.

awyr_agored
  • 613
  • 3
  • 19
  • 2
    Note that single apostrophes are not the notation for single characters in Rebol (if leading it's a quoting character, if in the middle of the word it's an identifier character). So characters are **#"x"**. However, [changing this is being discussed right now...](https://forum.rebol.info/t/removing-from-legal-word-characters-any-objections/1180) (and it's Wednesday by my clock :-P) – HostileFork says dont trust SE Jul 10 '19 at 15:57

3 Answers3

4

If you don't want to use loops, there's one nifty trick:

>> head extract/into str 1 []  
== [#"T" #"o" #"d" #"a" #"y" #" " #"i" #"s" #" " #"M" #"o" #"n" #"d" #"a" #"y"]

OTOH, string! is already a series of char! values, so breaking it up into characters like that doesn't provide any clear benefit.

9214
  • 2,105
  • 11
  • 15
  • thank you! Just so that I understand; 'extract' each character in the string of size '1' column; refinement 'into' stores characters into array buffer; a block data type is formed; return the series at its 'head'? – awyr_agored Jul 11 '19 at 00:05
  • 1
    @awyr_agored you can study how `extract` works in detail with `source extract`, but basically it extracts (hence the name) values from series (`string!` in this case) at regular intervals (here it is `1`). `/into` says where to put extracted values - I gave it an empty `block!`. `head` here is to reset block back to the beginning, because in R2 `extract/into` for some reason returns a tail. – 9214 Jul 11 '19 at 06:29
3

In some Rebols (not Rebol2) you could use MAP-EACH to do this, e.g. map-each ch str [ch].

In Rebol2, COLLECT and KEEP are fairly general and powerful ways of building up blocks:

>> collect [foreach c str [keep c]]
== [#"T" #"o" #"d" #"a" #"y" #" " #"i" #"s" #" " #"M" #"o" #"n" #"d" #"a" #"y"]

I'll give you that one and let others list out the infinity of faster ways. :-)

0

Depending if you want to get single characters or strings with the length one you can use parse too with the following rules

>> str: "Today is Monday"
== "Today is Monday"
>> collect [parse/all str [some [copy x  skip (keep x)    ]     ]]
== ["T" "o" "d" "a" "y" " " "i" "s" " " "M" "o" "n" "d" "a" "y"] 
>> collect [parse/all str [some [x: skip (keep x/1)]]]
== [#"T" #"o" #"d" #"a" #"y" #" " #"i" #"s" #" " #"M" #"o" #"n" #"d" #"a" #"y"]

Red allows a tighter version

>>   parse str [collect [some [keep skip]]]
== [#"T" #"o" #"d" #"a" #"y" #" " #"i" #"s" #" " #"M" #"o" #"n" #"d" #"a" #"y"]
sqlab
  • 6,412
  • 1
  • 14
  • 29