Map over n consecutive elements inside a list

Problem

I have a list of elements, and I want to map using a function when on each loop the function gets n items from a list.

e.g.:

for list (1 2 3 4 5) and N = 2 it will call:

(fn 1 2)
(fn 2 3)
(fn 3 4)
(fn 4 5)

for list '(1 2 3 4 5) and N = 3 it will call:

(fn 1 2 3)
(fn 2 3 4)
(fn 3 4 5)

and collect the results into a single list.

Solution

The code use function: * take from recipe: Select first n elements from list

(define (sublist-map n fn lst)
  (let loop ((lst lst) (result '()))
    (if (< (length lst) n)
        (reverse result)
        (let ((next-list (take lst n)))
          (loop (cdr lst) (cons (apply fn next-list) result))))))

NOTE: This looping overlap the list, so window is always moving one element per loop. If you want the whole window to move to the next n elements you can use this solution instead:

(define (group-map n fn seq-list)
  (map (lambda (lst)
         (apply fn lst))
       (group n seq-list)))

Above function uses: * function group from recipe: Split list into groups of N elements

Credit: Jakub T. Jankiewicz

Usage

(sublist-map 2 < '(1 2 3 4))
;; ==> (#t #t #t)
(sublist-map 3 = '(2 2 2 3 3 3 4 4 4))
;; ==> (#t #f #f #t #f #f #t)

(group-map 3 = '(2 2 2 3 3 3 4 4 4))
;; ==> (#t #t #t)
(group-map 3 = '(2 2 2 0 1 2 4 4 4))
;; ==> (#t #f #t)
(group-map 3 + '(2 2 2 3 3 3 4 4 4))
;; ==> (6 9 12)
(group-map 3 max '(1 2 3 4 5 6 7 8 9))
;; ==> (3 6 9)

Back to the Scheme Cookbook