实现以Clojure惯用的方式反转序列

时间:2014-04-14 19:19:34

标签: clojure

任务是编写一个反转序列的函数。我试图尽可能高效地实现这一目标,但我无法找到最好的方法。创建变量并开始将项目附加到该变量并不是正确的。对我来说似乎是惯用的是,如果有办法做到以下几点:

来自Clojure文档

(map-indexed (fn [idx itm] [idx itm]) "foobar")
--> ([0 \f] [1 \o] [2 \o] [3 \b] [4 \a] [5 \r])

我所做的是:

(defn testing [x]
(map-indexed (fn [idx itm] [(- (count x) idx) itm]) x))

哪个收益率:

(testing "foobar")
--> ([6 \f] [5 \o] [4 \o] [3 \b] [2 \a] [1 \r])

我无法弄清楚如何将其重新打包到具有正确索引的新列表中。老实说,即使是声明变量的概念,目前也在Clojure中逃避了。我所有的经验都是使用Python和Ruby。

2 个答案:

答案 0 :(得分:4)

字符串是可查询的,因此我们可以使用clojure.core/reduce

(defn rev [x]
  (reduce #(str %2 %1) x))

(rev "foobar") ;; "raboof"

我们的想法是,对于每次迭代,我们都会创建一个新字符串,它是当前字符串前面序列中的下一个字符。

  

我所有的经验都是使用Python和Ruby

Ruby

中的情况相同
def rev(x)
  x.chars.reduce { |s, c| c + s }
end

非字符串

(defn rev [x]
  (reduce conj () x))

(rev [1 2 3 4 5]) ;; (5 4 3 2 1)

答案 1 :(得分:1)

如您所提出的问题,您可以使用索引反转序列,如下所示:

(defn reverse [s]
  (let [v (vec s)] (map v (range (dec (count v)) -1 -1))))

......或者,反过来说,

(def reverse (comp rseq vec))