On this page:
6.4.1 (Sequenceof Integer):   pick rows
6.4.2 Slice:   pick rows in a length-aware way
6.4.3 Slice-Dots:   preserve remaining axes
6.4.4 Integer:   remove an axis
6.4.5 Slice-New-Axis:   add an axis

6.4 Slicing🔗ℹ

One common array transformation is slicing: extracting sub-arrays by picking rows from each axis independently.

Slicing is done by applying array-slice-ref or array-slice-set! to an array and a list of slice specifications corresponding to array axes. There are five types of slice specification:

Create Slice objects using :: and Slice-New-Axis objects using ::new. There is only one Slice-Dots object, namely ::....

When slicing an array with n axes, unless a list of slice specifications contains ::..., it must contain exactly n slice specifications.

The remainder of this section uses the following example array:
> (define arr
    (build-array
     #(2 3 4)
     (λ: ([js : Indexes])
       (string-append* (map number->string (vector->list js))))))
> arr

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]

   #[#["100" "101" "102" "103"]

     #["110" "111" "112" "113"]

     #["120" "121" "122" "123"]]])

6.4.1 (Sequenceof Integer): pick rows🔗ℹ

Using a sequence of integers as a slice specification picks rows from the corresponding axis. For example, we might use lists of integers to pick every row from every axis:
> (array-slice-ref arr (list '(0 1) '(0 1 2) '(0 1 2 3)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]

   #[#["100" "101" "102" "103"]

     #["110" "111" "112" "113"]

     #["120" "121" "122" "123"]]])

This simply copies the array.

More usefully, we can use sequences to swap rows on the same axis:
> (array-slice-ref arr (list '(1 0) '(0 1 2) '(0 1 2 3)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["100" "101" "102" "103"]

     #["110" "111" "112" "113"]

     #["120" "121" "122" "123"]]

   #[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]])

We can also remove rows:
> (array-slice-ref arr (list '(0 1) '(0 2) '(0 2)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["000" "002"] #["020" "022"]] #[#["100" "102"] #["120" "122"]]])

> (array-slice-ref arr (list '(0 1) '(0 1 2) '()))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#[] #[] #[]] #[#[] #[] #[]]])

Or duplicate rows:
> (array-slice-ref arr (list '(0 1) '(0 1 2) '(0 0 1 2 2 3)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "000" "001" "002" "002" "003"]

     #["010" "010" "011" "012" "012" "013"]

     #["020" "020" "021" "022" "022" "023"]]

   #[#["100" "100" "101" "102" "102" "103"]

     #["110" "110" "111" "112" "112" "113"]

     #["120" "120" "121" "122" "122" "123"]]])

However, a sequence slice specification cannot alter the number of axes.

Using sequence constructors like in-range, we can pick every even-indexed row in an axis:
> (array-slice-ref arr (list '(1 0) '(0 1 2) (in-range 0 4 2)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["100" "102"]

     #["110" "112"]

     #["120" "122"]]

   #[#["000" "002"]

     #["010" "012"]

     #["020" "022"]]])

We could also use in-range to pick every row instead of enumerating their indexes in a list, but that would require another kind of tedium:
> (define ds (array-shape arr))
> (array-slice-ref arr (list (in-range (vector-ref ds 0))
                             (in-range (vector-ref ds 1))
                             (in-range (vector-ref ds 2))))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]

   #[#["100" "101" "102" "103"]

     #["110" "111" "112" "113"]

     #["120" "121" "122" "123"]]])

The situation calls for an in-range-like slice specification that is aware of the lengths of the axes it is applied to.

6.4.2 Slice: pick rows in a length-aware way🔗ℹ

As a slice specification, a Slice object acts like the sequence object returned by in-range, but either start or end may be #f.

If start is #f, it is interpreted as the first valid axis index in the direction of step. If end is #f, it is interpreted as the last valid axis index in the direction of step.

Possibly the most common slice is (::), equivalent to (:: #f #f 1). With a positive step = 1, start is interpreted as 0 and end as the length of the axis. Thus, (::) picks all rows from any axis:
> (array-slice-ref arr (list (::) (::) (::)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]

   #[#["100" "101" "102" "103"]

     #["110" "111" "112" "113"]

     #["120" "121" "122" "123"]]])

The slice (:: #f #f -1) reverses an axis:
> (array-slice-ref arr (list (::) (::) (:: #f #f -1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["003" "002" "001" "000"]

     #["013" "012" "011" "010"]

     #["023" "022" "021" "020"]]

   #[#["103" "102" "101" "100"]

     #["113" "112" "111" "110"]

     #["123" "122" "121" "120"]]])

The slice (:: 2 #f 1) picks every row starting from index 2:
> (array-slice-ref arr (list (::) (::) (:: 2 #f 1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["002" "003"]

     #["012" "013"]

     #["022" "023"]]

   #[#["102" "103"]

     #["112" "113"]

     #["122" "123"]]])

The slice (:: 1 #f 2) picks every odd-indexed row:
> (array-slice-ref arr (list (::) (::) (:: 1 #f 2)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["001" "003"]

     #["011" "013"]

     #["021" "023"]]

   #[#["101" "103"]

     #["111" "113"]

     #["121" "123"]]])

Notice that every example starts with two (::). In fact, slicing only one axis is so common that there is a slice specification object that represents any number of (::).

6.4.3 Slice-Dots: preserve remaining axes🔗ℹ

As a slice specification, a Slice-Dots object represents any number of leftover, adjacent axes, and preserves them all.

For example, picking every odd-indexed row of the last axis can be done by
> (array-slice-ref arr (list ::... (:: 1 #f 2)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["001" "003"]

     #["011" "013"]

     #["021" "023"]]

   #[#["101" "103"]

     #["111" "113"]

     #["121" "123"]]])

For arr specifically, ::... represents two (::).

Slicing only the first axis while preserving the rest can be done by
> (array-slice-ref arr (list '(0) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#["000" "001" "002" "003"]

     #["010" "011" "012" "013"]

     #["020" "021" "022" "023"]]])

If more than one ::... appears in the list, only the first is expanded:
> (array-slice-ref arr (list ::... '(1) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["001"] #["011"] #["021"]] #[#["101"] #["111"] #["121"]]])

> (array-slice-ref arr (list ::... '(1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["001"] #["011"] #["021"]] #[#["101"] #["111"] #["121"]]])

If there are no leftover axes, ::... does nothing when placed in any position:
> (array-slice-ref arr (list ::... '(1) '(1) '(1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["111"]]])

> (array-slice-ref arr (list '(1) ::... '(1) '(1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["111"]]])

> (array-slice-ref arr (list '(1) '(1) ::... '(1)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["111"]]])

> (array-slice-ref arr (list '(1) '(1) '(1) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[#["111"]]])

6.4.4 Integer: remove an axis🔗ℹ

All of the slice specifications so far preserve the dimensions of the array. Removing an axis can be done by using an integer as a slice specification.

This example removes the first axis by collapsing it to its first row:
> (array-slice-ref arr (list 0 ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#["000" "001" "002" "003"]

   #["010" "011" "012" "013"]

   #["020" "021" "022" "023"]])

Removing the second axis by collapsing it to the row with index 1:
> (array-slice-ref arr (list (::) 1 ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#["010" "011" "012" "013"] #["110" "111" "112" "113"]])

Removing the second-to-last axis (which for arr is the same as the second):
> (array-slice-ref arr (list ::... 1 (::)))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#["010" "011" "012" "013"] #["110" "111" "112" "113"]])

All of these examples can be done using array-axis-ref. However, removing an axis relative to the dimension of the array (e.g. the second-to-last axis) is easier to do using array-slice-ref, and it is sometimes convenient to combine axis removal with other slice operations.

6.4.5 Slice-New-Axis: add an axis🔗ℹ

As a slice specification, (::new dk) inserts dk into the resulting array’s shape, in the corresponding axis position. The new axis has length dk, which must be nonnegative.

For example, we might conceptually wrap another #[] around an array’s data:
> (array-slice-ref arr (list (::new) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#[#["000" "001" "002" "003"]

       #["010" "011" "012" "013"]

       #["020" "021" "022" "023"]]

     #[#["100" "101" "102" "103"]

       #["110" "111" "112" "113"]

       #["120" "121" "122" "123"]]]])

Or duplicate the array twice, within two new outer rows:
> (array-slice-ref arr (list (::new 2) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array

 #[#[#[#["000" "001" "002" "003"]

       #["010" "011" "012" "013"]

       #["020" "021" "022" "023"]]

     #[#["100" "101" "102" "103"]

       #["110" "111" "112" "113"]

       #["120" "121" "122" "123"]]]

   #[#[#["000" "001" "002" "003"]

       #["010" "011" "012" "013"]

       #["020" "021" "022" "023"]]

     #[#["100" "101" "102" "103"]

       #["110" "111" "112" "113"]

       #["120" "121" "122" "123"]]]])

Of course, dk = 0 is a valid new axis length, but is usually not very useful:
> (array-slice-ref arr (list (::) (::new 0) ::...))

- : #(struct:Array

      (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>

      #<syntax:build/user/8.15.0.2/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)

(array #[#[] #[]])

Inserting axes can also be done using array-axis-insert.