Question

I have (games scores) data in this format:

Hotspurs Giants 356 6 275 4 442 3

Fierce Lions Club 371 3 2520 5 0 4

Mountain Tigers 2519 2 291 6 342 1

Shooting Stars Club 2430 5 339 1 2472 2

Gun Tooters 329 4 2512 2 2470 6

Banshee Wolves 301 1 2436 3 412 5

The first two/three words represent the club's names, thereafter follows 6 blocks of data per row which represents the club's round-by-round scores and opponent index (starting from 1). In the data above 3 rounds have been played by each team. Hotspurs Giants (index 1) played Banshee Wolves (6) in the 1st round scoring 356 to Banshee's 301, in round 2 Hotspurs Giants played Shooting Stars Club (4) scoring 275 - 339 and in round 3 played Mountain Tigers (3) scoring 442 to Tiger's 342

My question is how to parse this blocks of data in the most efficient way possible such that each club's data will be in the format below considering that a club's name may comprise of two (2) or more words.

Viz

[Club Round Score Opponent Opponent-Score] for each club

Was it helpful?

Solution

Assuming data is:

data: [
    Hotspurs Giants 356 6 275 4 442 3
    Fierce Lions Club 371 3 2520 5 0 4
    Mountain Tigers 2519 2 291 6 342 1
    Shooting Stars Club 2430 5 339 1 2472 2
    Gun Tooters 329 4 2512 2 2470 6
    Banshee Wolves 301 1 2436 3 412 5
]

I think this solves the problem, please check the result:

clubs: copy []
parse data [
    some [
        copy club some word!
        copy numbers some number!
        (append clubs reduce [form club numbers])
    |
        skip
    ]
]
new-line/all/skip clubs yes 2

list: copy []
parse clubs [
    some [
        set club string! into [
            copy numbers some number! (
                i: 1
                foreach [score index] numbers [
                    append list reduce [
                        club score
                        pick clubs index * 2 - 1
                        pick pick clubs index * 2 i
                    ]
                    i: i + 2
                ]
            )
        ]
        | skip
    ]
]

new-line/all/skip list yes 4

Afterwards if you probe clubs you should get:

CLUBS is a block of value: [
    "Hotspurs Giants" [356 6 275 4 442 3]
    "Fierce Lions Club" [371 3 2520 5 0 4]
    "Mountain Tigers" [2519 2 291 6 342 1]
    "Shooting Stars Club" [2430 5 339 1 2472 2]
    "Gun Tooters" [329 4 2512 2 2470 6]
    "Banshee Wolves" [301 1 2436 3 412 5]
]

And if you probe list the output is:

LIST is a block of value: [
    "Hotspurs Giants" 356 "Banshee Wolves" 301
    "Hotspurs Giants" 275 "Shooting Stars Club" 339
    "Hotspurs Giants" 442 "Mountain Tigers" 342
    "Fierce Lions Club" 371 "Mountain Tigers" 2519
    "Fierce Lions Club" 2520 "Gun Tooters" 2512
    "Fierce Lions Club" 0 "Shooting Stars Club" 2472
    "Mountain Tigers" 2519 "Fierce Lions Club" 371
    "Mountain Tigers" 291 "Banshee Wolves" 2436
    "Mountain Tigers" 342 "Hotspurs Giants" 442
    "Shooting Stars Club" 2430 "Gun Tooters" 329
    "Shooting Stars Club" 339 "Hotspurs Giants" 275
    "Shooting Stars Club" 2472 "Fierce Lions Club" 0
    "Gun Tooters" 329 "Shooting Stars Club" 2430
    "Gun Tooters" 2512 "Fierce Lions Club" 2520
    "Gun Tooters" 2470 "Banshee Wolves" 412
    "Banshee Wolves" 301 "Hotspurs Giants" 356
    "Banshee Wolves" 2436 "Mountain Tigers" 291
    "Banshee Wolves" 412 "Gun Tooters" 2470
]

OTHER TIPS

Here is one example (using Rebol 3) showing how this could be done:

club-data: map []  ; store data in hash map is one option

foreach line read/lines %games-scores.txt [
    fields: split line space

    ; lets take last 6 cols of data
    scores: reverse collect [loop 6 [keep to-integer take/last fields]]

    ; and whats left is the club name
    club-name: form fields

    ; build club data
    club-data/(club-name): scores
]

Above assumes data is in file games-scores.txt and returns you a MAP! (hash map) called club-data where your club data would look like this:

make map! [
    "Hotspurs Giants" [356 6 275 4 442 3]
    "Fierce Lions Club" [371 3 2520 5 0 4]
    "Mountain Tigers" [2519 2 291 6 342 1]
    "Shooting Stars Club" [2430 5 339 1 2472 2]
    "Gun Tooters" [329 4 2512 2 2470 6]
    "Banshee Wolves" [301 1 2436 3 412 5]
]

One caveat... READ/LINES will load whole file into memory. So if games-scores.txt is big you should look at using OPEN instead and read in one line at a time.

Update - re: your comment here is same example in Rebol 2 [tested in REBOL/Core 2.7.8.2.5 (2-Jan-2011)]:

club-data: make hash! []  ; of course doesn't have to be hash!

foreach line read/lines %games-scores.txt [
    fields:    parse line none
    scores:    reverse collect [loop 6 [keep to-integer take/last fields]]
    club-name: form fields
    append club-data reduce [club-name scores]
]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top