如何在ClojureScript中移动范围?
例如,让我们说我们有范围:
(range 3)
给出:(0 1 2)
我正在寻找一个将值向左移动的函数:(1 2 0)
或类似(2 0 1)
我想出了一个我将分享的实现作为答案。我想应该是一些内置函数来做到这一点?但我没有找到任何东西。
答案 0 :(得分:2)
这是我写的函数:
(defn <-range [n l]
(concat (drop n (range l)) (range n)))
简要说明:
(range l)
创建一个长度为l (drop n)
删除n个元素(range n)
创建一个新范围,直到n (concat)
连接两个范围如果我尝试:
(<-range 0 4)
提供(0 1 2 3)
(<-range 2 4)
提供(2 3 0 1)
(<-range 4 4)
提供(0 1 2 3)
答案 1 :(得分:1)
我已经颠倒了你的args的顺序,因为这更接近于range
args的工作方式。 lazy-cat
可能优于concat
,因为它甚至无法评估第二个range
,直到需要它为止。
(defn <-range [length start-index]
(lazy-cat (range start-index length)
(range start-index)))
答案 2 :(得分:1)
还有一个cycle
函数,(不出所料)循环一个集合(以避免连接):
user> (defn <-range [n l]
(->> (range l)
cycle
(drop n)
(take l)))
#'user/<-range
user> (<-range 0 4)
(0 1 2 3)
user> (<-range 2 4)
(2 3 0 1)
user> (<-range 4 4)
(0 1 2 3)
根据余下的内容,即使没有调用range
,你也可以这样做:
user> (defn <-range [n l]
(take l (iterate #(rem (inc %) l) (rem n l))))
或者像这样:
user> (defn <-range [n l]
(map #(rem (+ % n) l) (range l)))
答案 3 :(得分:1)
我认为range
仅用作示例,您真的希望能够对任何集合执行此操作。
(defn rotate-left [c]
(lazy-cat (drop 1 c) (take 1 c)))
或能够选择性地指定多于1次旋转,
(defn rotate-left
([c] (rot-left 1 c))
([n c] (lazy-cat (drop n c) (take n c))))
使用这个,
(rotate-left (range 3))
会产生(1, 2, 0)
和
(rotate-left 2 (range 3))
会产生(2, 0, 1)