How do I access a specific element in a vector of

2020-03-16 11:58发布

If I have a vector defined as

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

How in clojure do I access a random element in a vector of vectors? I keep seeing people say online that one of the benefits to using a vector over a list is that you get random access instead of having to recurse through a list but I haven't been able to find the function that allows me to do this. I'm used to in c++ where I could do matrix[1][1] and it would return the second element of the second vector.

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

5条回答
Lonely孤独者°
2楼-- · 2020-03-16 12:39

The other answers are probably all that you need, but if you're doing 2D indexing a lot--perhaps along with other transformations of 2D numeric structures--you might want to look into the core.matrix library. Switching between different core.matrix implementations with different performance characteristics is usually a one-line change. One of the implementations consists of operations on Clojure vectors. Here's how you would do the double-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 that particular operation, core.matrix provides no particular advantage. If you want to iterate through the matrix to generate a new one, here's one way to do it:

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

Of course it's not very hard to do that with core Clojure functions. Whether core.matrix is useful depends on what you want to do, obviously.

查看更多
▲ chillily
3楼-- · 2020-03-16 12:42

Vectors are associative, so you can use get-in to access nested vectors, e.g. matrices, by coordinates.

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

(get-in matrix [1 1])
;=> 5
查看更多
何必那么认真
4楼-- · 2020-03-16 12:48

You can use the same approach to Mars answer above, with to-array-2d implemented in 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
查看更多
爷、活的狠高调
5楼-- · 2020-03-16 12:51

Almost like you would do it 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 one argument, which they presume is an index and look up in themselves as if by nth, i.e. vectors are functions of their indices.

查看更多
爷的心禁止访问
6楼-- · 2020-03-16 12:56

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

user=> (def matrix [[1 2 3][4 5 6]])
user=> (get-in matrix [1 1])
5
查看更多
登录 后发表回答