# [ACCEPTED]-Idiomatic sequence slice in Clojure-slice

Score: 35

You can simplify all the ones using `count` by 10 using `take-last` or `drop-last` instead:

``````(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
``````

And as suggested in the 9 comments below, you can use the `->>` macro to 8 "thread" several operation together. For 7 example, the last two lines could also be 6 written like this:

``````(->> 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
``````

I think the two methods 5 are both very readable if you are only applying 4 two operations to a list, but when you have 3 a long string like `take`, `map`, `filter`, `drop`, `first` then using the 2 `->>` macro can make the code much easier to 1 read and probably even easier for to write.

Score: 26

Python's notion of a sequence is very different 10 from Clojure's.

In Python,

• a sequence is a finite ordered set indexed by non-negative numbers; and
• a list is a mutable sequence which you can add slices to or remove slices from.

In Clojure,

• a sequence is an interface supporting `first`, `rest`, and `cons`;
• a list is an immutable sequential collection with `cons` (or `rest`) adding (or removing) `first` elements (returning lists so modified, anyway).

The 9 nearest thing in Clojure to a Python list 8 is a vector. As Adam Sznajder suggests, you can slice it using `subvec`, though 7 you can't add or remove slices as you can 6 in Python.

`subvec` is a fast constant-time operation, whereas 5 `drop` makes you pay for the number of elements 4 bypassed (`take` makes you pay for the elements 3 you traverse, but these are the ones you 2 are interested in).

``````(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]
``````
Score: 11

There is a function `subvec`. Unfortunately, it 2 only works with vectors so you would have 1 to transform your sequence:

http://clojuredocs.org/clojure_core/clojure.core/subvec

Score: 5

Slicing a sequence is a bit of a "code 7 smell" - a sequence in general is designed 6 for sequential access of items.

If you are 5 going to do a lot of slicing / concatenation, there 4 are much better data structures available, in 3 particular checkout the RRB-Tree vector 2 implementation:

This supports very efficient 1 `subvec` and `catvec` operations.

More Related questions