Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is clojure.core equivalent of lodash _.pluck

Lodash _.pluck does this

var users = [
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 }
];

_.pluck(users, 'user');
// → ['barney', 'fred']

Good thing about it is it can also go deep like this:

var users = [
  { 'user': {name: 'barney'}, 'age': 36 },
  { 'user': {name: 'fred'},   'age': 40 }
];

_.pluck(users, 'user.name');
// ["barney", "fred"]

Is there equivalent in Clojure core of this? I mean, I can easily create one line somewhat like this

(defn pluck
  [collection path]
  (map #(get-in % path) collection))

And use it like this:

(def my-coll [{:a {:z 1}} {:a {:z 2}}])
(pluck my-coll [:a :z])
=> (1 2)

I was just wondering if there's such thing already included in Clojure and I overlooked it.

like image 513
ma2s Avatar asked Jun 13 '15 08:06

ma2s


3 Answers

There is no built-in function for this. You can refer to clojure.core API reference and the cheatsheet to look up what's available.

I would say Clojure's syntax is light enough that it feels sufficient to use a combination of map and an accessor utility like get-in.

This also demonstrates a well-adopted principle in Clojure community: provide mostly simple defaults and let the users compose them as they need. Some people would probably argue that pluck conflates iteration and querying.

like image 50
Valentin Waeselynck Avatar answered Oct 22 '22 04:10

Valentin Waeselynck


The most simple way is something like:

(map #(:user %) users)

It will return list '(36 40)

like image 38
Glen Swift Avatar answered Oct 22 '22 03:10

Glen Swift


Here are simple tricks:

(def my-coll [{:a {:z 1}} {:a {:z 2}}])

(map :a my-coll)
 => ({:z 1} {:z 2})

(map (comp :z :a) my-coll)
 => (1 2)

Works because keyword behaves like a function as well.

like image 41
ma2s Avatar answered Oct 22 '22 05:10

ma2s