How to access a specific element in a clojure vector

If I have a vector defined as

(def matrix [[1 2 3][4 5 6]]) 

How in clojure to access a random element of a vector of vectors? I constantly see people saying on the Internet that one of the advantages of using a vector over a list is that you get random access instead of rewriting the list, but I could not find a function that allows me to do this. I'm used to in C ++, where I could make a matrix [1] [1], and it will return the second element of the second vector.

Am I stuck to loop one element at a time through my vector, or is there an easier way to access certain elements?

+6
source share
5 answers

Almost the same as you did in C ++:

 user=> (def matrix [[1 2 3][4 5 6]]) user=> (matrix 1) [4 5 6] user=> ((matrix 1) 1) 5 

As the docs say :

Vectors implement IFn for invoke () of a single argument, which they assume is an index and look on their own, as if on the nth, that is, the vectors are functions of their indices.

+9
source

Vectors are associative, so you can use get-in to access nested vectors, for example. matrices in coordinates.

 (def matrix [[1 2 3] [4 5 6] [7 8 9]]) (get-in matrix [1 1]) ;=> 5 
+13
source

The other answers are probably all you need, but if you do 2D indexing a lot - maybe along with other transformations of two-dimensional number structures - you can look in core.matrix . Switching between different core.matrix implementations with different performance characteristics is usually a one-line change. One of the implementations consists of operations with Clojure vectors. Here's how you would do dual indexing in core.matrix:

 user=> (use 'clojure.core.matrix) nil user=> (def m (matrix [[1 2 3][4 5 6]])) #'user/m user=> (mget m 1 1) 5 

For this particular operation, core.matrix does not offer much benefit. If you want to iterate over a matrix to generate a new one, here is one way to do this:

 user=> (emap inc m) [[2 3 4] [5 6 7]] 

Of course, this is not very difficult to do with the basic functions of Clojure. Whether core.matrix is ​​useful depends on what you want to do, obviously.

+3
source

Since vectors are associative data structures, you can also use get-in to access inside with nested indices:

 user=> (def matrix [[1 2 3][4 5 6]]) user=> (get-in matrix [1 1]) 5 
+2
source

You can use the same approach to Mars answer above, to-array-2d implemented in the clojure.core library :)

 user> (def a (to-array-2d [[1 2 3][4 5 6]])) #'user/a user> (alength a) 2 user> (alength (aget a 0)) 3 user> (aget a 0 0) 1 user> (aget a 0 1) 2 user> (aget a 0 2) 3 user> (aget a 1 0) 4 user> (aget a 2 0) ArrayIndexOutOfBoundsException 
+1
source

All Articles