Better way for Grouping rows in a series.

2 views
Skip to first unread message

Ged Byrne

unread,
Nov 23, 2006, 8:54:28 AM11/23/06
to REBOL
Hi,

After a long break I'm getting back into REBOL and I was wondering if
anybody could help me out with a few pointers on how to be more
REBOLious.

I'm using the following script to group data from a table.

It's pretty short, but I'm not happy with it. Can anybody recommend
improvements.

Thanks.

----

rebol[]
data: [
;Country Name
"UK" "John"
"US" "Bradley"
"UK" "George"
"US" "Cory"
"US" "Bret"
"UK" "Henry"
]

result: copy []

foreach country unique extract data 2 [
append result country
append/only result copy []
]

forskip data 2 [
append
select result first data
second data
]

probe result

----

The result is this:
[
"UK" ["John" "George" "Henry"]
"US" ["Bradley" "Cory" "Bret"]
]

Gregg Irwin

unread,
Nov 26, 2006, 12:49:20 PM11/26/06
to Ged Byrne
Hi Ged,

You might get a better response on the ML than here, but...

You could mod this for your needs. It expects the rows to be
sub-blocks, and it doesn't remove the column you're grouping by, but
it's a general solution. I think this was something I did early in my
REBOLing, so it could probably be greatly improved as well.

group-by: func [ ; See SPLIT
{Returns a block of blocks+sub-blocks with items partitioned by
matching index elements in each sub-block.}
block [any-block!] "A block of series values"
index [integer!] "Index of sub-series value to compare, for grouping."
/part "Compare part of the series, rather than a single value."
range [number!]
/local result val
][
result: copy []
either part [
; First, build up a list of keys, with empty blocks to go with each.
foreach item block [
val: copy/part at item index range
if not find/only/skip result :val 2 [repend result [:val copy []]]
]
; Find the correct place (key) to put an item, and add it there.
foreach item block [
val: copy/part at item index range
append/only select/only result :val item
]
][
; First, build up a list of keys, with empty blocks to go with each.
foreach item block [
val: item/:index
if not find/skip result :val 2 [repend result [:val copy []]]
]
; Find the correct place (key) to put an item, and add it there.
foreach item block [
val: item/:index
append/only select result val item
]
]
result
]

group-by [[a 1 2] [b 2 3] [a 2 4] [c 2 3] [b 1 5]] 1
group-by [[a 1 2] [b 2 3] [a 2 4] [c 2 3] [b 1 5] [c 2 4]] 2
group-by [[a 1 2] [b 2 3] [a 2 4] [c 2 3] [b 1 5] [c 2 4]] 3
group-by/part [[a 1 2] [b 2 3] [a 2 4] [c 2 3] [b 1 5] [c 2 4]] 1 2
group-by/part ["ABC" "AAC" "ABD"] 1 2


--Gregg

Oyster

unread,
Nov 30, 2006, 7:23:55 AM11/30/06
to REBOL
hi, Gregg, where is the mail-list and how can I join it?
thanx

Gregg Irwin

unread,
Nov 30, 2006, 10:45:23 AM11/30/06
to Oyster
Hi Oyster,

O> hi, Gregg, where is the mail-list and how can I join it?

See: http://www.rebol.com/discussion.html for details.

There is also an archive of old messages on REBOL.org.

--Gregg

Reply all
Reply to author
Forward
0 new messages