Printing Primitive Arrays in Clojure
Asked Answered
S

3

13

I am at the REPL, and I create a java array:

=> (def arr (double-array [1 2 3]))

Of course, if I want to look at my arr, I get:

=> arr
#<double[] [D@2ce628d8>

Is there anything I can do that will make arrays of java primitives print like clojure's persistentVectors?

=> arr
[1.0 2.0 3.0]

I know I could wrap my arrays in some sort of nice printing function (which is what I currently do), but this is a pain in cases, for example, where the vectors are part of a map:

=> my-map
{"1" #<double[] [D@47254e47>, "2" #<double[] [D@11d2625d>}
Sheeran answered 5/12, 2011 at 19:52 Comment(0)
E
19

Would something as simple as the following do?

user=> (seq arr)
(1.0 2.0 3.0)

If it's only for the REPL, then perhaps the technical semantics don't matter.

Update

It turns out that pretty print (pprint) works just fine with your map of vectors:

user=> (def my-map {"1" (double-array [1 2 3])
                    "2" (double-array [1 2 3])})
#'user/my-map
user=> (pprint my-map)
{"1" [1.0, 2.0, 3.0], "2" [1.0, 2.0, 3.0]}

Final Update: From the linked Google Groups discussion in the comments

Questioner found an answer he liked in a discussion paraphrased below:

> Is there any way to make the Clojure repl pretty-print by default?

Try:

(clojure.main/repl :print pprint)

> Thank you! That is exactly what I needed.

Enervate answered 5/12, 2011 at 20:46 Comment(3)
Thanks, scott. Pretty print is half of the answer here. The other half is: groups.google.com/group/clojure/browse_thread/thread/…Sheeran
Wow. That's really cool. I love it when we discover something together through Stack Overflow. High Fives for team work!Enervate
@ScottLowe: Please include that into your answer. It wouldn't hurt to have both halves in one place :)Chancellorship
S
1

The str function just calls the .toString of the Java object, which isn't too convenient on arrays. To get a nice representation (as others have also stated) (java.util.Arrays/toString arr) can be called.

However, how could this be implemented transparantly in normal clojure println and str code ? Could we implement a proxy on Array and replace the .toString method ? Or should we implement a new str2 protocol using str for everything except the Array class ?

My guess the proxied arr would be the best option, since that would work with other code that calls str on it, even if it was called from another namespace. No idea how to implement a proxy on Array though :)

Sackbut answered 5/12, 2011 at 20:23 Comment(0)
K
1

There is always the java interop solution:

(java.util.Arrays/toString arr)

So you would have

(map #(java.util.Arrays/toString (val %)) my-map)
Kettledrum answered 5/12, 2011 at 20:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.