Reputation: 132
I've currently implemented a way to sort by a deep key in a map like so:
(sort-by #(get-in % [:layer :order]) [{:layer {:order 1} {:layer {:order 2}])
I was wondering if there was a way to do this using map destructuring? Is that available for functions outside of let
and parameter definition? An example of what I'm wondering is possible:
(sort-by {:layer {:order}} [{:layer {:order 1} {:layer {:order 2}])
Upvotes: 1
Views: 78
Reputation: 3074
I don't think so because sort-by needs a value extraction function (keyfn)
(that is unless you want to sort entries directly by themself)
user=> (doc sort-by)
-------------------------
clojure.core/sort-by
([keyfn coll] [keyfn comp coll])
Returns a sorted sequence of the items in coll, where the sort
order is determined by comparing (keyfn item). If no comparator is
supplied, uses compare. comparator must implement
java.util.Comparator. If coll is a Java array, it will be modified.
To avoid this, sort a copy of the array.
EDIT: what you can do is "simulate" get-in
via compose and keyword lookups as in
(sort-by (comp :a :c) [ {:c {:a 3}} {:c {:a 2}} ])
Upvotes: 0
Reputation: 10624
As far as I'm aware, you can only destructure within a let binding or function binding. This is how you might do it with nested map destructuring:
(sort-by (fn [{{o :order} :layer}] o)
[{:layer {:order 2}}
{:layer {:order 1}}])
I don't think that's any clearer, though. Since keywords are functions, you could also use plain old function composition:
(sort-by (comp :order :layer)
[{:layer {:order 2}}
{:layer {:order 1}}])
Upvotes: 1