Reputation: 17775
I'm learning clojure and have been using 4clojure.com to get better. I just completed #19 but it seems like maybe I haven't done it quite as the author's have anticipated - like I've perhaps missed the point somehow.
Given the constraint that you cannot use the last function does this seem like a reasonable solution?
#(.get %(- (count %) 1))
Upvotes: 31
Views: 14503
Reputation: 11
(fn getLast [l] (if (= (count l) 1) (first l) (getLast (rest l))) )
Upvotes: 0
Reputation: 3933
I don't think my solution is better than anyone else but I think it is another way of solving the same problem:
(fn
[x]
(nth x (- (count x) 1)))
This is using the fn
.
Upvotes: 2
Reputation: 30538
I think you can get even simpler with something like (comp peek vec)
. I think the problem is that last
is working with sequences and works in linear time as the documentation says:
clojure.core/last ([coll]) Return the last item in coll, in linear time
peek
on the other hand is faster than last
according to the docs:
clojure.core/peek ([coll]) For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil.
Upvotes: 1
Reputation: 946
If you're going to use:
#(first (reverse %))
You might as well compose the function with "comp":
(comp first reverse)
This is probably a little more idiomatic and easier to read. The same caveat about "reverse" not being lazy applies here.
Upvotes: 43
Reputation: 7825
Here's a purely recursive approach that doesn't rely on counting:
(defn end [[n & more]] (if more (recur more) n))
Upvotes: 20
Reputation: 1745
Yeah that's a reasonable solution. A few things though:
It's more idiomatic to use the function dec
instead of subtracting by one.
#(.get % (dec (count %)))
Follow other people on 4clojure. That way you can see their solutions to the problem after you solve it. I'm working through 4clojure myself and find it very useful to learn about the language, especially certain idioms.
The first solution I thought of would just be to reverse the list and take the first element.
#(first (reverse %))
Upvotes: 8
Reputation: 3212
That's a valid solution. I would go with #(nth % (dec (count %)))
as being more idiomatic, but they're functionally equivalent.
Upvotes: 32