2011-10-30 29 views
13

tôi đã xác định 3 chức năng sau sử dụng REPL leiningen:Tại sao hàm chuỗi của tôi trả về một [email protected]?

(defn rand-int-range [floor ceiling] (+ floor (rand-int (- ceiling floor))))

(defn mutate-index 
    "mutates one index in an array of char and returns the new mutated array" 
    [source idx] 
    (map 
    #(if (= %1 idx) 
     (char (+ (int %2) (rand-int-range -3 3))) 
     %2) 
    (iterate inc 0) 
    source)) 

(defn mutate-string 
    [source] 
    (str 
    (mutate-index 
     (.toCharArray source) 
     (rand-int (alength (.toCharArray source)))))) 

Khi tôi chạy (mutate-string "hello"), thay vì REPL in ra chuỗi biến đổi, nó được in ra clojure.lang. LazySeq @ xxxxxx trong đó 'xxxxx' là một chuỗi ngẫu nhiên các số và chữ cái. Tôi hy vọng nó thay vì in một cái gì đó như "hellm" Điều này thực sự cho tôi một chuỗi trở lại như tôi nghĩ? Nếu có, làm thế nào tôi có thể lấy REPL để chỉ cho tôi chuỗi đó?

Trả lời

16

1) Để chuyển đổi một chuỗi các ký tự (đó là những gì mutate-index trả về) thành một chuỗi, hãy sử dụng apply str thay vì chỉ str. Sau này hoạt động trên các đối tượng, không phải trình tự.

(str [\a \b \c]) 
=> "[\\a \\b \\c]" 

(apply str [\a \b \c]) 
=> "abc" 

2) Strings là seqable, nghĩa là bạn có thể sử dụng chức năng tự như mapfilter trên chúng trực tiếp mà không thứ như .toCharArray.

3) Xem xét sử dụng map-indexed hoặc StringBuilder để thực hiện những gì bạn đang cố gắng để làm:

(apply str (map-indexed (fn [i c] (if (= 3 i) \X c)) "foobar")) 
=> "fooXar" 

(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X))) 
=> "fooXar" 
+0

Cảm ơn Justin, # 1 ở trên đã trả lời câu hỏi của tôi. Tôi cũng sẽ xem xét # 2 và # 3 vì chúng dường như là lời khuyên tốt. Rõ ràng tôi là một noob clojure, vì vậy cảm ơn. – user1020853

7

Điều đó xảy ra, bởi vì chức năng bản đồ trả về một chuỗi lười biếng, mà chuỗi reprsentation chỉ là tên lớp và một băm ([email protected]).

Để có được tác phẩm gốc bạn cần trước tiên để có được chuỗi đánh giá lười biếng. Bằng cách sử dụng (áp dụng str ...) như Justin đã đề xuất điều đó sẽ xảy ra và bạn sẽ nhận được kết quả chính xác.

Nếu không bình thường nếu bạn thấy vấn đề tương tự do không đánh giá một chuỗi lười biếng bạn nên thử chức năng doall, mà buộc evalutation của một chuỗi lười biếng

0

Bất cứ khi nào tôi muốn để có được chuỗi giá trị của một chuỗi lười biếng tôi sử dụng clojure.core/pr-str:

user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (take 5 (range 100))) 
INFO user - This is a lazy seq [[email protected]] 
nil 
user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (pr-str (take 5 (range 100)))) 
INFO user - This is a lazy seq [(0 1 2 3 4)] 
nil 
+0

http://clojuredocs.org/clojure.core/pr-str 'pr thành một chuỗi, trả về chuỗi ' – n611x007

+0

Grrr. Điều này không tăng lên (nhưng tôi đã thấy nó hoạt động). Các tài liệu cho (pr-str) nói rằng nó "pr cho một chuỗi, trả lại nó" và các tài liệu cho (pr) nói "In các đối tượng (s) để dòng đầu ra đó là giá trị hiện tại của * out * ... "nhưng tôi không muốn nó đi * out *, tôi chỉ muốn lười biếng-seq hoàn toàn nhận ra. Methinks LazySeq có thể không phải là "Đơn giản" vì nó được quảng cáo. –

Các vấn đề liên quan