Reputation: 1359
I have a 2D vector that looks like this
(["2011-01-01" "2011" "01" "01"]
["1869-01-01" "1869" "01" "01"]
["1922-01-01" "1922" "01" "01"]
["1905-01-01" "1905" "01" "01"])
I want to have just a vector of just the second column so it will be like this
("2011" "1869" "1922" "1905")
What is the best way to do this in Clojure?
Upvotes: 1
Views: 277
Reputation: 2539
Possible answers
A. (reduce (fn [| [_ - ]] (conj | -)) [] data)
B. (map (fn [[_ - ]] -) data)
C. (map second data)
Upvotes: 1
Reputation: 29958
Be sure to always consult the Clojure CheatSheet for questions like this.
For something this simple, just use mapv
(or map
) and the second
function:
(def data [["2011-01-01" "2011" "01" "01"]
["1869-01-01" "1869" "01" "01"]
["1922-01-01" "1922" "01" "01"]
["1905-01-01" "1905" "01" "01"]])
(mapv second data) => ["2011" "1869" "1922" "1905"]
I prefer mapv
since it gives the result as a vector (non-lazy) which is easier to cut & paste w/o needing quotes.
If you have more complicated needs, you may wish to review the tupelo.array
library. Your data is already in the form of a Clojure 2-D array (vector of vectors), so you can just use the col-get
function:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.array :as ta]))
(def data ...)
; Note zero-based indexing
(ta/col-get data 1) => ["2011" "1869" "1922" "1905"]
The library includes many other functions for input/output, get/set values, flip arrays up/down or left/right, rotation, adding/deleting rows & cols, etc. There is also a version that works with mutable arrays (Java native object arrays) instead of Clojure immutable data structures.
Upvotes: 3