Reputation: 47
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
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 lambda
s 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