2017-04-21 24 views
2

我想創建一個函數,當你輸入一個數字時,它會返回一個從1到5的所有數字的向量,即[1 2 3 4 5 ]Clojure - 返回所有整數到一定數字的函數

到目前爲止,我在

(defn counter [number] 
     (let [x 1 
      result []] 
     (when (<= x number) 
     (conj result x) 
     (inc x)))) 

現在,它會把1到載體,但我想說現在(inc x),並通過再次運行。我必須使用復發嗎?

任何幫助深表感謝

+3

'(range 1(inc number))'或者,得到一個向量'(vec(range ...))' – leetwinski

回答

3

有一個內置函數range。爲了實現自己的目標(數字矢量從1到包括性N)可以按如下把它包裝:

(defn get-range [n] 
    (->> n inc (range 1) vec)) 

(get-range 5) 
#=> [1 2 3 4 5] 

此外,您還可以去使用iterate功能

(defn get-range [n] 
    (->> (iterate inc 1) 
     (take n) 
     vec)) 

或者使用一個循環:

(defn get-range [n] 
    (loop [m 1 
     res []] 
    (if (> m n) 
     res 
     (recur (inc m) (conj res m))))) 
5

從@ fl00r的回答都很好,但我想在一個還原一個以及拋出:

可還原對於這種使用情況更好的選擇,因爲

  • range用Clojure 1.7被重建爲自還原的,更長久的開始/步/結束值的特殊情況下,它會使用原始的在自我減少期間。
  • 使用到傳感器的形式表示,最後的向量可以直接內置,而不是建立一個懶序列,然後把它變成一個載體
  • 構建載體時into會自動使用瞬態 - 有一個小的開銷(與循環方法相比),但在較大範圍內節省大量費用
  • 由於您正在構建混凝土集合(矢量),所以懶惰不會帶來好處,因此熱切的方法更有意義
  • 這種方法比任何序列方法的時間和內存效率要高得多。 range作爲reducible將消耗堆空間(只有幾個當地人)。瞬態矢量是通過填充數組構建的,然後根據需要直接構建持久性矢量節點。通過比較,所有的序列方法都會對迭代器進行盒裝數學計算,構建多個嵌套的緩存序列值,然後將這些值逐個複製到向量中。上面使用的循環方法將使用原始數學,並獲得一些性能優勢(但仍然存在向向量與瞬變添加元素的缺點)。

快速PERF測試(針對不同大小的矢量):

 
Size |  range/vec | iterate/vec | loop/recur | loop/recur' | range/into | 
-----|---------------|---------------|---------------|---------------|---------------| 
    1 | 160.968880 ns | 180.287974 ns | 40.373079 ns | 79.203722 ns | 136.157046 ns | 
    10 | 378.058753 ns | 851.381372 ns | 342.720391 ns | 200.658997 ns | 253.015756 ns | 
100 | 2.486726 µs | 8.034826 µs | 3.464423 µs | 1.471333 µs | 1.760118 µs | 
1000 | 23.349414 µs | 88.188242 µs | 37.247193 µs | 16.443044 µs | 17.109882 µs | 

逆足試驗是用繞圈快速板凳上的Java 1.8/1的Clojure做。8個

版本進行測試:

  • 範圍/ VEC - 第一示例從@ fl00r - 原始數學,1個序列,瞬變
  • 迭代/ VEC - 從@ fl00r第二示例 - 盒裝數學,2個序列,瞬變
  • 環路/ RECUR - 從@ fl00r 3ND例如 - 原始數學,0的序列,沒有瞬變
  • 環路/ RECUR」 - 相同之前,但修改爲使用瞬變 - 原始數學,0序列,瞬變
  • 範圍/成 - 在這個答案的上方的例子 - 原始數學,0序列,瞬態

注意的是,過去兩年中也有類似的特徵,但環/復發」大量採用了更多的代碼:

(defn get-range [n] ;; loop/recur' 
    (loop [m 1 
     res (transient [])] 
    (if (> m n) 
     (persistent! res) 
     (recur (inc m) (conj! res m))))) 
+0

真棒!謝謝! – fl00r