[racket-users] Iterating through a list more than one at a time
I feel like there should be a simpler way to do this, but I haven't found one despite much Googling and reading of docs about "for" and its siblings. Can someone point me the right way? I'd like to be able to iterate over a list N elements at a time -- e.g., grab elements 1 and 2, do something with them, grab 3 and 4, etc. This will do the job, but I suspect there's a more built-in way: (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) (define (step-by-n func data [num 2]) (if (null? data) (func '()) (append (func (take data num)) (step-by-n func (drop data num) num (step-by-n (lambda (l) (if (null? l) '() (list (hash (car (first l)) (car (second l)) data) (step-by-n (lambda (l) (if (null? l) '() (list (hash (car (first l)) (list (car (second l)) (car (third l))) data 3) OUTPUT: '(#hash(("foo" . "bar")) #hash(("baz" . "jaz")) #hash(("quux" . "glug"))) '(#hash(("foo" . ("bar" "baz"))) #hash(("jaz" . ("quux" "glug" (Note that the fact that it returns the results as a list was a deliberate choice but not an essential one.) -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Iterating through a list more than one at a time
On Aug 4, 2016, at 3:10 PM, David Storrs wrote: > I'd like to be able to iterate over a list N elements at a time -- e.g., grab > elements 1 and 2, do something with them, grab 3 and 4, etc. Your technique seems fine. You could use `split-at` if you wanted to save a list operation, otherwise it's the standard recursion pattern: #lang racket (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) (define (step-by-n func xs [num 2]) (if (null? xs) null (let-values ([(head tail) (split-at xs num)]) (cons (func head) (step-by-n func tail num) (step-by-n (λ (xx) (apply hash (map car xx))) data) (step-by-n (λ (xxx) (hash (caar xxx) (map car (cdr xxx data 3) I wrote a utility function called `slice-at` to handle this problem. [1] [1] http://docs.racket-lang.org/sugar/#%28def._%28%28lib._sugar%2Flist..rkt%29._slice-at%29%29 -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Iterating through a list more than one at a time
Great, thank you. I was thinking maybe there was some construct that could do this built-in, the way 'map' can double as 'zip'. I looked through sugar and it looks very convenient; I'll be using it in future. Note that when I installed it, I got the following: [...snip lots of "raco setup: 0 skipping: /..." lines] raco setup: docs failure: query-exec: unable to open the database file error code: 14 SQL: "ATTACH $1 AS other" database: # mode: 'read-only file permissions: (write read) raco setup: --- installing collections --- raco setup: --- post-installing collections --- raco pkg install: packages installed, although setup reported errors Doesn't seem to have mattered and it might just be something weird about permissions on my system. I figured I'd mention it, though. Dave On Thu, Aug 4, 2016 at 5:04 PM, Matthew Butterick wrote: > > On Aug 4, 2016, at 3:10 PM, David Storrs wrote: > > I'd like to be able to iterate over a list N elements at a time -- e.g., > grab elements 1 and 2, do something with them, grab 3 and 4, etc. > > Your technique seems fine. You could use `split-at` if you wanted to save > a list operation, otherwise it's the standard recursion pattern: > > #lang racket > (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) > > (define (step-by-n func xs [num 2]) > (if (null? xs) > null > (let-values ([(head tail) (split-at xs num)]) > (cons (func head) (step-by-n func tail num) > > (step-by-n (λ (xx) (apply hash (map car xx))) data) > > (step-by-n (λ (xxx) (hash (caar xxx) (map car (cdr xxx data 3) > > > I wrote a utility function called `slice-at` to handle this problem. [1] > > > [1] http://docs.racket-lang.org/sugar/#%28def._%28%28lib._ > sugar%2Flist..rkt%29._slice-at%29%29 -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Iterating through a list more than one at a time
> I feel like there should be a simpler way to do this, but I haven't found > one despite much Googling and reading of docs about "for" and its siblings. > Can someone point me the right way? > > I'd like to be able to iterate over a list N elements at a time -- e.g., > grab elements 1 and 2, do something with them, grab 3 and 4, etc. > > This will do the job, but I suspect there's a more built-in way: > > (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) racket/sequence provides an `in-slice` sequence to use with `for` forms: https://docs.racket-lang.org/reference/sequences.html#%28def._%28%28lib._racket%2Fsequence..rkt%29._in-slice%29%29 -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Iterating through a list more than one at a time
On Wed, Aug 10, 2016 at 5:50 AM, Greg Hendershott wrote: > > I feel like there should be a simpler way to do this, but I haven't found > > one despite much Googling and reading of docs about "for" and its > siblings. > > Can someone point me the right way? > > > > I'd like to be able to iterate over a list N elements at a time -- e.g., > > grab elements 1 and 2, do something with them, grab 3 and 4, etc. > > > > This will do the job, but I suspect there's a more built-in way: > > > > (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) > > racket/sequence provides an `in-slice` sequence to use with `for` forms: > > https://docs.racket-lang.org/reference/sequences.html#% > 28def._%28%28lib._racket%2Fsequence..rkt%29._in-slice%29%29 > in-slice produces lists of N elements, so I guess if I wanted to iterate over every 2nd element I would use something like this?: (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug"))) (for ((x (~> data in-list (in-slice _ 2) (map car ...do something...) -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Iterating through a list more than one at a time
Yes. Also each slice is a sequence. So you could do all the usual things to it. Including but not limited to using another `for` form, applying it to afunction, or destructuring it using `match` and friends. In these examples I included an extra, "leftover" element to make sure it was handled: #lang racket (define data '(("foo") ("bar") ("baz") ("jaz") ("quux") ("glug") ("EXTRA"))) (for/list ([slice (in-slice 2 data)]) (for/list ([x slice]) x)) (for/list ([slice (in-slice 2 data)]) (apply list slice)) (for/list ([slice (in-slice 2 data)]) (match slice [(list x y) (list x y)] [(list x) (list x)])) All eval to: '((("foo") ("bar")) (("baz") ("jaz")) (("quux") ("glug")) (("EXTRA"))) -- 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 racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.