Mir*_*lov 24 clojure sequence slice
在Python中,有一种方便的方法可以获取名为"切片"的列表的一部分:
a = [1,2,3,4,5,6,7,8,9,10] # ? a = range(1,10)
a[:3] # get first 3 elements
a[3:] # get all elements except the first 3
a[:-3] # get all elements except the last 3
a[-3:] # get last 3 elements
a[3:7] # get 4 elements starting from 3rd (? from 3rd to 7th exclusive)
a[3:-3] # get all elements except the first 3 and the last 3
Run Code Online (Sandbox Code Playgroud)
clojure.repl/doc在Clojure中玩,我找到了所有这些的等价物,但我不确定它们是不是惯用的.
(def a (take 10 (iterate inc 1)))
(take 3 a)
(drop 3 a)
(take (- (count a) 3) a)
(drop (- (count a) 3) a)
(drop 3 (take 7 a))
(drop 3 (take (- (count a) 3) a))
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何在Clojure中切片序列?换句话说,返回序列不同部分的正确方法是什么?
Dao*_*Wen 32
您可以count使用take-last或drop-last代替简化所有使用的:
(def a (take 10 (iterate inc 1)))
(take 3 a) ; get first 3 elements
(drop 3 a) ; get all elements except the first 3
(drop-last 3 a) ; get all elements except the last 3
(take-last 3 a) ; get last 3 elements
(drop 3 (take 7 a)) ; get 4 elements starting from 3
(drop 3 (drop-last 3 a)) ; get all elements except the first and the last 3
Run Code Online (Sandbox Code Playgroud)
并且正如下面的评论中所建议的那样,您可以使用->>宏将几个操作"线程化"在一起.例如,最后两行也可以这样写:
(->> a (take 7) (drop 3)) ; get 4 elements starting from 3
(->> a (drop-last 3) (drop 3)) ; get all elements except the first and the last 3
Run Code Online (Sandbox Code Playgroud)
我认为这两种方法都非常可读的,如果你只应用两个操作的列表,但是当你有一个长串像take,map,filter,drop,first然后使用->>宏可以使代码更容易阅读和可能甚至更容易的写.
Thu*_*ail 22
Python的序列概念与Clojure非常不同.
在Python中,
在Clojure,
Clojure中最接近Python列表的是向量.正如Adam Sznajder建议的那样,你可以使用它来切片subvec,尽管你不能像在Python中那样添加或删除切片.
subvec是一个快速的恒定时间操作,而drop让你支付绕过的元素数量(take让你支付你遍历的元素,但这些是你感兴趣的元素).
你的例子变成......
(def a (vec (range 1 (inc 10))))
(subvec a 0 3)
; [1 2 3]
(subvec a 3)
; [4 5 6 7 8 9 10]
(subvec a 0 (- (count a) 3))
; [1 2 3 4 5 6 7]
(subvec a (- (count a) 3))
; [8 9 10]
(subvec a 3 (+ 3 4))
; [4 5 6 7]
(subvec a 3 (- (count a) 3))
; [4 5 6 7]
Run Code Online (Sandbox Code Playgroud)
Ada*_*der 11
有一个功能subvec.不幸的是,它只适用于矢量,所以你必须转换你的序列:
http://clojuredocs.org/clojure_core/clojure.core/subvec
切片序列有点"代码味道" - 一般来说序列是为了顺序访问项目而设计的.
如果要进行大量切片/连接,可以使用更好的数据结构,特别是检查RRB-Tree向量实现:
这支持非常有效subvec和catvec操作.
| 归档时间: |
|
| 查看次数: |
8691 次 |
| 最近记录: |