簡體   English   中英

在Clojure中遞歸遍歷向量

[英]Recursively run through a vector in Clojure

我才剛開始和Clojure一起玩。

如何遍歷項目向量?

我幼稚的遞歸函數將具有類似於經典地圖的形式。

(defn map [f xs] (
  (if (= xs [])
      []
      (cons (f (first xs)) (map f (rest xs))
  )
))

問題是我在網絡上找不到此類代碼的任何示例。 我發現了很多使用內置序列遍歷功能的示例,例如for,map和loop。 但是沒有人做原始的遞歸版本。

那是因為您不應該在Clojure中做這種事情嗎? (例如,因為它使用了沒有尾部調用優化之類的較低級Java原語?)?

當您說“遍歷向量”時,這是非常模糊的; 由於Clojure是一門輕率的工具,因此專門研究序列分析和操作,因此使用這種語言的好處在於,您不會以“遍歷向量然后對每個元素進行處理”的方式來思考,相反,您會習慣地說“將其從向量中抽出”或“將該向量轉換為X”或“我希望該向量給我X”。

正是由於使用Lisp語言的這種觀點,您將看到很多示例和生產代碼,它們不僅循環/重復通過向量,而且還專門以簡短,慣用的方式進行處理。 使用簡單的函數(如reduce map filter for into和其他函數),您可以優雅地在諸如矢量之類的序列上移動, 同時對內容進行所需的處理。 在大多數其他語言中,這至少是兩個不同的部分:循環,然后是執行所需操作的實際邏輯。

您會經常發現,如果使用C,C ++,Java等語言獲得的更命令性的思想來考慮序列,那么您的代碼(至少)比起初考慮時要長大約4倍。以更實用的方式制定您的計划。

Clojure 僅在使用尾遞歸時才重用堆棧幀,並且僅在使用顯式recur調用時才重用 其他所有內容都將消耗堆棧。 上面的地圖示例不是尾部遞歸,因為缺點是在遞歸調用之后發生的,因此不能以任何語言進行TCO。 如果您將其切換為使用延續傳遞樣式並使用顯式調用來代替map進行recur ,那么您應該很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM