在<ा href="https://www.surveymonkey.com/r/clojure2024">2024年Clojure状态调查中分享你的想法!

欢迎!请参阅关于页面了解更多有关如何使用此页面的信息。

0
序列

Range不包括结束参数。例如

> (range 1 3)
(1 2)

我想要一个类似于range,但包括结束状态的函数

> (inclusive-range 1 3)
(1 2 3)

不幸的是,这并不等同于将结束值添加到range返回的seq中。例如

> (inclusive-range 1 2.5)
(1 2)

我不认为Clojure中有直接提供这一功能的,但我发现这个函数很方便。我已经写了一个这样的函数(但不是惰性的)

(defn inclusive-range
  "Return a sequence of nums from START to END, both inclusive, by STEP."
  ([start end]
   (inclusive-range start end 1))
  ([start end step]
   (let [test-for-done (if (< start end)
                         >
                         <)]
     (if (test-for-done start (+ start step))
       []
       (loop [nums []
              cur start]
         (if (test-for-done cur end)
           nums
           (recur (conj nums cur)
                  (+ cur step))))))))

我是遗漏了一个更好的方法吗?这能被添加到Clojure中去吗?

2个回答

+1

我经常需要这样的功能,因此编写了`thru`函数

`
tupelo.core/thru

(thru end)
(thru start end)
(thru start end step)

返回一个数字序列。类似于clojure.core/rng,但包括右边界值。不是惰性的。
`

0

有一个简单的想法,尽管我不完全确定我是否理解了你所有的需求/想法

> (defn inclusive-end-range 
    [start end]
    (range start (inc end)))
#'inclusive-end-range
> (inclusive-end-range 1 3)
(1 2 3)
OP明确包括了那个情况

不幸的是,这并不等同于将结束值添加到range返回的seq中。例如

> (inclusive-range 1 2.5)
(1 2)

(range 1 (inc 2.5)) => (1 2 3)而不是。
这似乎会被floor涵盖,所以`#(range %1 (inc (Math/floor %2)))`。当添加步长参数时,会变得稍微复杂一些,但这做的还是可以,而且比原始的基于`loop`的解决方案更简单。
Sean,你说得对 - 我误解了它。感谢澄清,对不起造成了噪音。
本来想写一个答案,但后来意识到我做不到,因为问题本身表述不清,这次讨论也展示了这一点。当你开始用分数值表示`end`时,谈论“包括末端”就变得没有意义了。例如`(inclusive-range 1 2.5)`明显不包括末端,即使在原始问题中也是如此。所以,如果函数的期望行为可以精确指定,就可以通过变换参数并将它们传递给`range`来实现,这将是直接的。正如Eugene Pakhomov提到的,这大概需要将步长值加到`end`上,然后使用`floor`函数从结果中导出`range`要使用的`end`值。
...