1

I'd like to do vector creation inside a function.

(map #([first %]) coll_of_tuples)

This gives the error

ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:429)

Any workaround besides using list? I'm looking for short notation.

m33lky
  • 7,055
  • 9
  • 41
  • 48
  • 2
    Would this work `(map #(vector (first %)) coll_of_tuples)`? – peter Mar 08 '17 at 12:49
  • Yes, that works. In this situation I don't require a vector. It's sad that other short-hand notations don't work inside `#()`. – m33lky Mar 08 '17 at 13:00
  • 1
    Making them "work" would require changing the composability of Clojure's semantics, so this is *good*, not sad. `#()` is shorthand for function creation. Combining Clojure syntax as `#([...])` means to create a vector, then wrap in an invokable function. The invokable function you want is vector construction. The function for that is `vector`. +1 to peter's answer which says what you mean. – Alex Miller Mar 08 '17 at 15:26
  • @AlexMiller I see why that didn't work. I was so focused on extracting the first "column" from data that I thought of `map_fn` as a final shape for the row. – m33lky Mar 08 '17 at 16:00
  • Possible duplicate of [Clojure: returning a vector from an anonymous function](http://stackoverflow.com/questions/4921566/clojure-returning-a-vector-from-an-anonymous-function) – glts Mar 08 '17 at 18:47
  • @glts I'm looking for short-hand notation. That question is related though. It has something that hasn't been said here: `(map #(identity [(first %)])` coll) – m33lky Mar 08 '17 at 19:36

4 Answers4

2

If you want a shorter version there is a few options:

(map #(-> [(first %)]) coll)

(map #(do [(first %)]) coll)

(map (juxt first) coll)
ClojureMostly
  • 4,652
  • 2
  • 22
  • 24
  • another one could be `(map (comp vector first) ...)` – birdspider Mar 08 '17 at 14:07
  • While these are terse (I particularly like the juxt one), I find they are harder to understand at a glance. – Alex Miller Mar 08 '17 at 15:33
  • The first and second versions are terse versions of precisely what I was trying to do and address the requirements for a `map_fn`. – m33lky Mar 08 '17 at 16:04
  • @AlexMiller I think `juxt` is more confusing because only one value is considered, i.e. there is no juxtaposition. – m33lky Mar 09 '17 at 10:16
2

I like peter's answer in the comments of

(map #(vector (first %)) coll_of_tuples)

Or alternately

(map #(-> % first vector) coll_of_tuples)

Or leaning on FP more and anon fn less:

(map (comp vector first) coll_of_tuples)

If you instead prefer to think of this as extracting the first 1-length sequence from each, this is a seq-ier answer:

(map #(take 1 %) coll_of_tuples)
Alex Miller
  • 69,183
  • 25
  • 122
  • 167
1

If I needed the vector type I'd use (map #(vector (first %)) coll_of_tuples) as suggested by peter. So far it appears that list is the shortest notation.

m33lky
  • 7,055
  • 9
  • 41
  • 48
0

You could also use for, which is very similar to map except for giving a symbolic name to each element of the sequence in turn:

(for [tuple coll_of_tuples] 
  [(first tuple)])

This is not quite as minimal as some of the other solutions, but in some instances it is nice to have a named symbol like tuple instead of %.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48