clojure是否具有完全包容的范围功能?

时间:2015-10-08 00:58:33

标签: clojure

Clojure的range功能包括startend中的独占功能(如果提供)。核心库中的某个功能是否会提供完全包容(开始和结束)范围?

我发现在某些情况下必须调整结束值的代码 - 例如向下而不是向上(比如在列表理解中)的范围更不易读。 E.g:

(range n -1 -1)

我只是在文档中遗漏了它,还是有更清洁的方法来做到这一点?

我对guava Range API有一些喜爱,所以我一直在寻找类似灵活性的东西。

5 个答案:

答案 0 :(得分:4)

没有标准inclusive-range功能 - 遵循Kevin Ingle的术语。

您可以在range

之上构建一个
(defn inclusive-range
  ([] (range))
  ([end] (range (inc end)))
  ([start end] (range start (inc end)))
  ([start end step] (range start (+ end step) step)))

但是你遇到了破烂不堪的问题。例如,

(inclusive-range 10 11.5)
;(10 11 12)

我认为不是你想要的。

答案 1 :(得分:1)

AFAIK没有核心功能,但你可以定义自己的功能:

(defn inclusive-range [start end] (range start (inc end)))

或者更一般 - 定义一个只添加结尾的函数:

(defn inclusive-range [start end step] (flatten (list (range start end step) end)))

正如评论中指出的,上述解决方案可能并不理想。你提到你习惯了番石榴的范围,所以你也可以导入它并使用它:

(import 'com.google.common.collect.Range)
(-> (Range/closed 1 10)
    (.contains 10))  ; returns true

答案 2 :(得分:1)

也许你想写一些这样的函数:

(defn my-range [start & {:keys [up-to down-to]}]
  (cond (and (nil? up-to) (nil? down-to)) (range (inc start))
        (nil? down-to) (range start (inc up-to))
        :else (range start (dec down-to) -1)))

user> (my-range 10)
(0 1 2 3 4 5 6 7 8 9 10)

user> (my-range 0 :up-to 10)
(0 1 2 3 4 5 6 7 8 9 10)

user> (my-range 10 :down-to -10)
(10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10)

稍微冗长一点,但它符合simlpe范围行为,并添加了一些含糖的语法。

答案 3 :(得分:0)

Clojure中没有标准的包含范围函数,但是您可以通过

(defn inclusive-range [n] (map inc (range 0 n)))
(inclusive-range 10)

范围0也将增加,因此请保持-1

针对同一问题的另一种解决方案

(defn inclusive-range [count] (range 0 (+ 1 count) ))

答案 4 :(得分:0)

您可以定义与 range 等效但包含的内容,如下所示:

(defn irange
  ([start end step]
   (take-while (if (pos? step) #(<= % end) #(>= % end)) (iterate #(+ % step) start)))
  ([start end]
   (irange start end 1))
  ([end]
   (irange 0 end))
  ([] (range)))