[racket-users] Iterating through a list more than one at a time

2016-08-04 Thread David Storrs
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

2016-08-04 Thread Matthew Butterick

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

2016-08-04 Thread David Storrs
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

2016-08-10 Thread Greg Hendershott
> 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

2016-08-10 Thread David Storrs
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

2016-08-11 Thread Greg Hendershott
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.