Fantastic. Thanks, Michael. On Mon, May 4, 2020 at 10:39 PM Michael MacLeod <[email protected]> wrote:
> I'm not sure this is possible with only using `match` patterns. A > combination of the `list-rest` and `app` patterns as well as the `in-slice` > procedure from `racket/sequence` should do the trick, though: > > #lang racket > > (require racket/match) > > (define (collect-optional-vals x) > (for/list ([y (in-slice 4 x)]) > y)) > > (match '(req-a req-b name1 age1 first1 last1 name2 age2 first2 last2) > [(list-rest req-a req-b (app collect-optional-vals optional-vals)) > (list req-a req-b optional-vals)]) > > On Mon, May 4, 2020 at 7:16 PM David Storrs <[email protected]> > wrote: > >> I'm trying to write a parser for a CSV file with optional columns. >> Simplified version: There are 2 mandatory columns, after which there can >> be 0+ 4-column groups describing a person. Each group has the same column >> headers. >> >> ; legal column arrangements: >> RequiredA RequiredB >> RequiredA RequiredB Name Age First Last >> RequiredA RequiredB Name Age First Last Name Age First Last >> >> >> ; illegal: if an optional group is present, it must have all 4 columns >> RequiredA RequiredB Name Age First Last Name >> >> I thought I could do this straightforwardly with `match`, but I'm wrong. >> Can someone point me to the way to write such a match clause? >> >> >> Various failed attempts: >> (list reqA reqB (opt1 opt2 opt3 opt4) ...) ; syntax error. matching >> clauses do not do grouping like this >> (list reqA reqB (list opt1 opt2 opt3 opt4) ...) ; didn't expect this to >> work since it would specify an embedded list. I was right. >> >> This one surprised me: >> (match row >> [(list required1 required2 (and opt1 opt2 opt3 opt4) ...) >> (list opt1 opt2 opt3 opt4)]) >> >> This distributes the ... over the four items inside the 'and' clause such >> that each of the 'optionalN' identifiers matches all remaining elements. >> '(("Name" "Age" "First" "Last") >> ("Name" "Age" "First" "Last") >> ("Name" "Age" "First" "Last") >> ("Name" "Age" "First" "Last")) >> >> In hindsight it makes sense -- the 'and' causes it to match the element >> across all four patterns. They all match because they are identifiers and >> therefore match anything. Then the '...' causes it to do that for all >> remaining elements, generating lists into each of the identifiers because >> that's what '...' does. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/racket-users/CAE8gKocCPSgVQG_aMSC%3DQJAmAtxvmCN8vqpwsankKnCJZAOotw%40mail.gmail.com >> <https://groups.google.com/d/msgid/racket-users/CAE8gKocCPSgVQG_aMSC%3DQJAmAtxvmCN8vqpwsankKnCJZAOotw%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAE8gKocyrT%3DAUAzvkiWs6AxP118LrxX89CFNOzHf%2BJKj4pdGLQ%40mail.gmail.com.

