2011-12-05 11 views
12

Sono al REPL, e creo un array di Java:stampa array primitivi in ​​Clojure

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

Naturalmente, se voglio guardare il mio arr, ottengo:

=> arr 
#<double[] [[email protected]> 

C'è qualcosa che posso fare per far sì che gli array di primitive java vengano stampati come persistentVector s di clojure?

=> arr 
[1.0 2.0 3.0] 

So che avrei potuto avvolgere le mie matrici in una sorta di piacevole funzione di stampa (che è quello che attualmente faccio), ma questo è un dolore nei casi, per esempio, dove i vettori sono parte di una mappa:

=> my-map 
{"1" #<double[] [[email protected]>, "2" #<double[] [[email protected]>} 

risposta

18

Sarebbe qualcosa di semplice come la seguente do ?

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

Se è solo per REPL, forse la semantica tecnica non ha importanza.

Aggiornamento

Si scopre che abbastanza di stampa (pprint) funziona bene con la vostra mappa di vettori:

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]} 

aggiornamento finale: Dalla discussione legata Google Gruppi nei commenti

L'interrogante ha trovato una risposta che gli piaceva in una discussione parafrasata di seguito:

> Esiste un modo per rendere Clojure sostitutivo per impostazione predefinita?

Prova:

(clojure.main/repl :print pprint)

> Grazie! Questo è esattamente ciò di cui avevo bisogno.

+0

Grazie, scott. La bella stampa è metà della risposta qui. L'altra metà è: http://groups.google.com/group/clojure/browse_thread/thread/c9db56b8daeaffa2?fwc=1&pli=1 – charleslparker

+1

Wow. È davvero fantastico. Mi piace quando scopriamo qualcosa insieme attraverso Stack Overflow. High Fives per il lavoro di squadra! – Scott

+0

@ScottLowe: includilo nella risposta. Non sarebbe male avere entrambe le metà nello stesso posto :) –

1

la funzione str appena chiama la .toString dell'oggetto Java, che non è troppo conveniente su array. Per ottenere una bella rappresentazione (come altri hanno anche affermato) (java.util.Arrays/toString arr) può essere chiamato.

Tuttavia, come è possibile implementarlo in modo trasparente nel normale codice clojure println e str? Potremmo implementare un proxy su Array e sostituire il metodo .toString? O dovremmo implementare un nuovo protocollo str2 usando str per tutto tranne la classe Array?

Credo che l'arr con proxy sarebbe l'opzione migliore, poiché funzionerebbe con un altro codice che chiama str, anche se è stato chiamato da un altro spazio dei nomi. Non ho idea di come implementare un proxy su Array però :)

1

c'è sempre la soluzione Java interoperabilità:

(java.util.Arrays/toString arr) 

Così si avrebbe

(map #(java.util.Arrays/toString (val %)) my-map)