2024 Clojure 状态调查中分享您的想法!

欢迎!请查看关于页面,了解更多本网站的用途信息。

0
... 序列

范围不包括结束参数。例如

> (range 1 3)
(1 2)

我需要一个类似于 range 的函数,但是包含结束状态

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

不幸的是,这并不意味着将结束添加到 range 返回的序列中。例如

> (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)
by
原帖特别提到了这一情况

不幸的是,这并不意味着将结束添加到 range 返回的序列中。例如

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

(range 1 (inc 2.5)) => (1 2 3) instead.
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`值。
...