Block manipulation: help!
[1/2] from: mat:plothatching at: 13-Jun-2002 14:05
Hello folks,
Here's another newbish type question. I've never really gotten my head
around block/series manipulation in Rebol. As a result of this my code
is full of silly hacks that keep building temporary data structures to
get the results I want.
I was hoping that someone may help my cog drop into place so I can
write some decent Rebol at last.
Here's a typical problem;
Let's say we have a file which is full of cars and the colours they
are available in;
Saloon
"Red"
Coupe
"Red"
Coupe
"Yellow"
Pickup Truck
"Red"
Pickup Truck
"Yellow"
Pickup Truck
"Orange"
Pickup Truck
"Blue"
Now what if I want to scan through this file and build up a list of
cars but then just state which colours they are available in after in
the structure. I'll assuming an elegant format is this;
FinalData: make block! [
"Saloon" ["Red"]
"Coupe" ["Red" "Yellow"]
"Pickup Truck" ["Red" "Yellow" "Orange" "Blue"]
]
So, reading the file is easy enough.
CarLines: read/lines %file
foreach CarLine CarLines [
Car: pick (parse CarLine none) 1
Colour: pick (parse CarLine none) 2
;
; ???
;
]
The question is, how do I create final data? I can do a find on the
FinalData to see if a car is there already. But all this does is
return the data after. I've always been puzzled about the lack of a
word/function to return the position in a series/block of a find,
if found.
So anyhow, here's the best I can think of;
either found? find FinalData Car [
; Already have an entry for this car...
; Select at least allows retrieving of the block following our
; found element easily...
;
existingcolours: select FinalData Car
;
; Great so add the new colour to the existing colours
;
append existingcards Car
;
; But how do we poke it back? We don't have a position to do a poke?
;
????
][
;
; Plug in the new car, plug in the block which has the colour in it
;
append FinalData Car
append FinalData reduce[reduce[Colour]]
]
I don't really understand the block navigation issues to solve this
problem or to somehow poke more data in without having a position.
As usual any stupid stuff I've missed and elegant solutions
gratefully received.
Regards,
Mat Bettinson
[2/2] from: joel::neely::fedex::com at: 13-Jun-2002 9:42
Hi, Mat,
You're almost there! Here's a complete example (using a string for
the original raw data)...
rawdata: {
Saloon:Red
Coupe:Red
Coupe:Yellow
Pickup Truck:Red
Pickup Truck:Yellow
Pickup Truck:Orange
Pickup Truck:Blue
}
finaldata: []
foreach line parse/all rawdata "^/" [
if parse/all line [
copy type to ":" skip copy color to end
][
either colors: select finaldata type [
if none? find colors color [
append colors color
]
][
append finaldata reduce [
type reduce [color]
]
]
]
]
foreach [type colorlist] finaldata [
print [type ":" tab colorlist]
]
Mat Bettinson wrote:
> CarLines: read/lines %file
> foreach CarLine CarLines [
<<quoted lines omitted: 4>>
> ;
> ]
... or, more simply...
foreach carline read/lines %file [
;...
]
since you can use the block of lines directly in FOREACH.
> ;
> ; But how do we poke it back? We don't have a position to do a poke?
> ;
You don't. Blocks are mutable values, so when you APPEND to a block
you are modifying its content -- even if it happens to live inside
another block.
Hope this helps!
-jn-
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted