dd123
dd123

Reputation: 47

fetch n-elements from a list Racket

How can I fetch n-elements from a list, I know about first, rest etc, but what if I want the first 3 elements in a list,

I.E (get-first 3 (list 1 2 3 4 5 6)) -> (list 1 2 3)

(get-first 5 (list 54 33 2 12 11 2 1 22 3 44)) -> (list 54 33 2 12 11)

This is not homework, but this code will help me complete the bigger picture of an assignment, I am really stuck and just need a few hints. I am not allowed to use Lambda or build-list and no recursion, I somehow need to b able to do this with just map, filter, foldr etc...

Upvotes: 0

Views: 2446

Answers (1)

Óscar López
Óscar López

Reputation: 236142

As was mentioned by @AlexisKing, you can simply use the take procedure that's built-in in Racket:

(take '(1 2 3 4 5 6) 3)
=> '(1 2 3)

(take '(54 33 2 12 11 2 1 22 3 44) 5)
=> '(54 33 2 12 11)

If for some reason that's not allowed you can still roll your own version using higher-order procedures and no explicit recursion, but do notice that not using lambda is impossible, the allowed procedures you mention (map, filter, foldr) all receive a lambda as a parameter, and anyway all procedures in Scheme are lambdas under the hood.

Here's a contrived solution, passing an accumulator that remembers in what index we're in the input list while traversing it, and building the output list in the cdr part. It can't be done without using a lambda, but if it bothers you to see it there, extract it to a helper procedure and pass it along:

(define (get-first n lst)
  (reverse
   (cdr
    (foldr (lambda (e acc)
             (if (= (car acc) n)
                 acc
                 (cons (add1 (car acc))
                       (cons e (cdr acc)))))
           '(0 . ())
           (reverse lst)))))

It still works as expected, but never do such a complicated thing when a built-in procedure will do the same:

(get-first 3 '(1 2 3 4 5 6))
=> '(1 2 3)

(get-first 5 '(54 33 2 12 11 2 1 22 3 44))
=> '(54 33 2 12 11)

Upvotes: 2

Related Questions