Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Mapping by N elements

39 views
Skip to first unread message

WJ

unread,
Oct 31, 2012, 3:27:49 AM10/31/12
to
Samir Barjoud wrote:

> Is there any function or macro defined by Common Lisp that does the
> following?
>
> Example usage:
> ............
> (map-by (x y) '(1 2 3 4 5 6)
> (+ x y))
>
> => (3 7 11)
>
> (map-by (x y z) '(1 2 3 4 5 6)
> (* x y z))
>
> => (6 120)

Racket:

## func must return 2 values.
(define (map-by func lst)
(let loop ((lst lst) (result '()))
(if (null? lst)
(reverse result)
(begin
(let-values ([(val new-list) (func lst)])
(loop new-list (cons val result)))))))

(map-by ($(lst) (values (apply + lst) (rest lst))) (range 8))
--> '(28 28 27 25 22 18 13 7)

(map-by ($$(x y tl ...) (values (+ x y) tl)) (range 8))
--> '(1 5 9 13)

;; Group consecutive numbers or non-numbers.
(map-by (match-lambda
[(list (? number? n) ..1 tl ...) (values n tl)]
[(list (? (negate number?) x) ..1 tl ...) (values x tl)])
'(a b c 2 3 4 x y 5 z))
--> '((a b c) (2 3 4) (x y) (5) (z))

Given:

(define-syntax-rule ($ expr ...) (lambda expr ...))
(define-syntax-rule ($$ (pat ...) expr ...)
(match-lambda [(list pat ...) expr ...]))

danielrupi...@yahoo.es

unread,
Oct 31, 2012, 2:12:48 PM10/31/12
to
Better in common-lisp

(defmacro max-by (args lst &body body)
(let ((n (length args)))
`(loop for l = ,lst then (nthcdr ,n l) while l collect (apply (lambda ,args ,@body) (subseq l 0 ,n)))))


(max-by (x y) '(1 2 3 4 5 6) (+ x y))
(3 7 11)

danielrupi...@yahoo.es

unread,
Oct 31, 2012, 4:08:41 PM10/31/12
to
a
A better solution

(defmacro max-by (args lst &body body)
`(loop for ,args on ,lst by (lambda(x)(nthcdr ,(length args) x)) collect
(progn ,@body)))
0 new messages