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 步长)

返回一系列数字。像clojure.core/rng,但包括右边界值。不是懒加载的。
`

0
by

有一点点想法,虽然我不敢肯定完全理解了你的要求/想法

> (defn inclusive-end-range 
    [start end]
    (range start (inc end)))
#'inclusive-end-range
> (inclusive-end-range 1 3)
(1 2 3)
by
创始人具体讨论了那种情况

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

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

(range 1 (inc 2.5)) => (1 2 3)。
by
这似乎可以用`floor`来处理,所以`#(range %1 (inc (Math/floor %2)))`。当添加步长参数时,会变得更为复杂,但仍然可行,并且比原始基于`loop`的解决方案更简单。
by
Sean,你说得对 - 我误解了这个问题。感谢你的澄清,为造成的不便道歉。
by
我本来想写一个答案,但意识到我无法这样做,因为问题表述不当,这次讨论就说明了这一点。当你开始为 `end` 使用分数值时,讨论“包括结束”就没有意义了。例如 `(inclusive-range 1 2.5)` 显然不包含结束,即使在原始问题中也是如此。所以如果可以精确指定函数的期望行为,通过转换参数并将它们传递给 `range`,就可以简单实现。正如 Eugene Pakhomov 所说,这可能涉及到将步长值添加到 `end` 并对结果使用 `floor` 以推导出传递给 `range` 的 `end` 值的组合。
...