2016-01-30 50 views
1

我想要做的是爲序列中的每個單詞運行每個單詞,通過名爲transform的函數,該函數將按字母順序排序並且也變爲小寫字母。但是我回來的是nil ??doseq Clojure返回nil,不訪問函數

我猜我正在使用doseq錯誤,但它看起來不錯?任何人都可以給我一些指點嗎?

(defn sort-string [s] 
    (apply str (sort s))) 

(defn transform [word x] 
    (let [x (sort-string (str/lower-case word))] 
    (prn word) 
    (prn word))) 

(doseq [dictionary '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")] 
    (transform dictionary)) 
+3

doseq總是返回零 – noisesmith

+0

另外,您的轉換函數接受第二ARG(名爲'x'),即使你從未放棄它是任何東西,你立即重新綁定'x'到'sort-string'的返回值。 –

回答

1

下面是一個例子:

(def words ["one" "two" "three" "FouR" "wot" "Rheet" "nope" "#"]) 
(sort (map clojure.string/lower-case words)) 
;; => ("#" "four" "nope" "one" "rheet" "three" "two" "wot") 
+0

是不可能爲每個字符串傳遞一個函數?因爲它想讓x是單詞的排序版本。最終,一旦我得到那個排序,我想要傳遞排序和原始的單詞到地圖 –

3

doseq是這樣做的副作用而迭代項的序列。例如,把每個項目一個接一個上的隊列:

(doseq [msg messages] 
    (put-to-queue! msg)) 

,因爲它意在用於的副作用,不計算一些它返回nil

變換值(這是你正在嘗試做的),你可以使用for,其中有一個類似的語法doseq列表。您還可以使用mapfiltersort

2

doseq僅供副作用,您可以使用for,而是如果你想要的結果作爲一個序列,它的語法是一樣的doseq。

(for [wordset '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")] 
    (transform wordset)) 
=> ("eno" "otw" "eehrt" "foru" "otw" "eehrt" "enop" "#") 
+0

是的,因爲這將是理想的,那麼這種呼籲將變換與wordset永遠字符串在wordset?我想要做的就是將已排序的單詞和原始單詞傳遞到映射中 –

+0

'(到{}(for [單詞集...]((單元身份轉換)單詞集))' - 這將返回一個鍵/值對然後將它們全部放到散列圖 – noisesmith

+0

中,或者是否要爲每個單詞分別映射? – noisesmith

0

沒有與您transform功能,您doseq表達的問題。他們認爲你不知道如何信息在Clojure的程序繞過:

  • 函數參數是按值傳遞,並且是完全 不受評價。
  • A let綁定重新定義名稱。它不分配給現有的 。
  • 來自函數的唯一信息是其返回值 (忽略副作用)。

transform功能

  • 不使用其x參數
  • 打印其word參數 - 兩次 - 和返回nil

let綁定沒有效果。

你想要什麼就像...

(defn transform [word] 
    (sort-string (clojure.string/lower-case word))) 

或,更簡明地,

(def transform 
    (comp sort-string clojure.string/lower-case)) 

這將返回而不進行打印的副作用經變換的串。


正如其他人所解釋的,doseq是不適當的。它總是返回nil。只是......

(let [dictionary '("one" "two" "three" "FouR" "wot" "Rheet" "nope" "#")] 
    (map transform dictionary)) 

...給...

("eno" "otw" "eehrt" "foru" "otw" "eehrt" "enop" "#") 
+0

正在進行編輯,直到我編寫我的答案變換實際上是正確的。 – noisesmith