user3080600
user3080600

Reputation: 1359

Clojure - Slice a 2D vector vectically

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

Answers (2)

KobbyPemson
KobbyPemson

Reputation: 2539

Possible answers

A. (reduce (fn [| [_ - ]] (conj | -)) [] data)

B. (map (fn [[_ - ]] -) data)

C. (map second data)

Upvotes: 1

Alan Thompson
Alan Thompson

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

Related Questions