Reputation: 6467
Firstly; sorry if the terminology I'm using is incorrect, I'm still very new to clojure and the paradigm shift is taking some time.
I am trying to work with a function which takes the first item from a set which is greater than twelve (is a 'teen' number). I can write this when I'm just applying it directly to a set, but I'm unsure how to write the function within a map. Can anyone point me in the right direction?
I tried a few things, typically along the lines of (partial (first (filter (partial < 12))))
but without any luck at all so far, and researching definitions of filter/partial has not yet proved fruitful.
TL/DR I want to have, as a value in a map, a function which takes the first item in a list which is greater than 12.
(def test-set [1, 8, 15, 22, 29])
(def some-functions {
:first first
:last last
:teenth "I don't know what to put here"
})
(first (filter (partial < 12) test-set))
Upvotes: 0
Views: 90
Reputation: 11
I found a small improvement to @jas' answer.
The functions
#(first (filter (partial < 12) %))
and
(defn teenth [coll] (first (filter (partial < 12) coll)))
use a combination of first
and filter
.
This is a use case for the some
function as stated on clojuredocs.org [1].
I would propose to refactor the functions to
(fn [coll] (some #(if (< 12 %) %) coll))
and
(defn teenth [coll] (some #(if (< 12 %) %) coll))
Due to the slightly more complex predicate function #(if (< 12 %) %)
we cannot use partial
anymore.
Please be aware that you cannot create nested anonymous functions by using the reader macro #()
[2]. In this case, you have to use fn
to create the nested anonymous function as shown above.
Actually, you could use fn
twice, but in my opinion it's not readable anymore:
(fn [coll] (some (fn [e] (if (< 12 e) e)) coll))
[1] https://clojuredocs.org/clojure.core/some#example-542692c6c026201cdc326940
[2] https://clojure.org/reference/reader#_dispatch
Upvotes: 1
Reputation: 10865
One way is to use an anonymous function when defining the map (https://riptutorial.com/clojure/example/15544/defining-anonymous-functions)
> (def some-functions {
:first first
:last last
:teenth #(first (filter (partial < 12) %))})
> ((:first some-functions) test-set)
1
> ((:last some-functions) test-set)
29
> ((:teenth some-functions) test-set)
15
Of course you could also have explicitly defined your function and used it in your map:
> (defn teenth [coll] (first (filter (partial < 12) coll)))
> (def some-functions {
:first first
:last last
:teenth teenth})
(As an aside, be careful with the word set
. In clojure sets are unordered collections of unique values. https://clojure.org/reference/data_structures)
Upvotes: 1