Language > Arrays > Array Subscript Ranges

# Array Subscript Ranges

Subscript ranges are used to select a subarray from an array by giving the starting and ending subscripts of the subarray in each dimension. Subscript ranges can be combined with scalar and array subscripts and with other subscript ranges. Any rectangular portion of an array can be selected with subscript ranges.

## Types of Subscript Ranges

There are six types of subscript ranges:

Subscript Format | Description
`[*]` | All elements of a dimension. This form is used with multidimensional arrays to select all elements along the dimension. For example, if `arr` is a 10-column by 12-row array, `arr[*, 11]` is the last row of `arr`, composed of elements `[arr[0,11], arr[1,11], ..., arr[9,11]]`, and is a 10-element row vector. Similarly, `arr[0, *]` is the first column of `arr`, `[arr[0,0], arr[0,1],..., arr[0,11]]`, and its dimensions are 1 column by 12 rows.
`[s`0`:s`1`]` | Subscript range from `s`0 to `s`1. This denotes all elements whose subscripts range from the expression `s`0 through `s`1(`s`0 must not be greater than `s`1). For example, if the variable `vec` is a 10-element vector, `vec[4:8]` is a five-element vector composed of `vec[4]` through `vec[8]`. Negative indices may be used, where `-1` indicates the last element. For example, `vec[-6:-2]` returns the same five elements as `vec[4:8]`.
`[s`0`:*]` or `[s`0`:-1]` | A range from the given element to the last element of dimension. This denotes all elements from a given element to the last element of the dimension. If the variable `vec` is a 50-element vector, `vec[10:*]` is a 40-element vector made from `vec[10]` through `vec[49]`.
`[s`0`:s`1`:n]` | Every `n`-th element in a range of subscripts from `s`0 to `s`1. The expression `n` is referred to as the subscript stride. The stride value may be positive or negative (but must not be zero). If the stride is positive then `s`0 must be less than or equal to `s`1. If the stride is negative then `s`0 must be greater than or equal to `s`1. If the stride is 1, then the result is identical in meaning to [`s`0`:s`1], as described above. For example, if the variable `vec` is a 50-element vector, `vec[5:13:2]` is a five-element vector composed of `vec[5]`, `vec[7]`, `vec[9]`, `vec[11]`, and `vec[13]`. In another example, `vec[-1:0:-3]` would return every third element of `vec`, in reverse order.
`[s`0`:*:n]` or `[s`0`:-1:n]` | Every `n`-th element from element `s`0 to the end of the dimension. The expression `n` is referred to as the subscript stride. If the variable `vec` is a 50-element vector, `vec[10:*:4]` is a 10-element vector made from every fourth element between `vec[10]` through `vec[46]`.
`[n]` | A simple subscript, either positive or negative. Positive subscripts are indexed from the beginning of the array, while negative subscripts are indexed from the end (where `-1` is the last element). When used with multidimensional arrays, simple subscripts specify only elements with subscripts equal to the given subscript in that dimension.

Multidimensional subarrays can be specified using any combination of the above forms. For example, if `arr` is a 10x10 array, `arr[*,0:4]` returns a 10 x 5 array that is made from all columns of rows 0 to 4 of `arr`.

## Dimensionality of Subarrays

The dimensions of an extracted subarray are determined by the size in each dimension of the subscript range expression. In general, the number of dimensions is equal to the number of subscripts and subscript ranges. The size of the n-th dimension is equal to one if a simple subscript was used to specify that dimension in the subscript; otherwise, it is equal to the number of elements selected by the corresponding range expression.

Degenerate dimensions (trailing dimensions with a size of one) are removed. If `arr` is a 10-column by 12-row array, the expression `arr[*,11]` results in a row vector with a single dimension. (The result of the expression is a 10-column by 1-row array; the last dimension is degenerate and is removed.) On the other hand, the expression `arr[0, *]` became a column vector with dimensions of [1, 12], showing that the structure of columns is preserved because the dimension with a size of one does not appear at the end.

To see this, enter the following statements in IDL:

arr = INDGEN(10,12)

HELP, arr

HELP, arr[*,11]

HELP, arr[0,*]

In the following examples, `vec` is a 50-element floating-point vector, and `arr` is a 10-column by 12-row integer array. Some typical subscript range expressions are as follows:

vec = BINDGEN(50)

arr = BINDGEN(10,12)

; Elements 5 through 10 of vec, a six-element vector.

print, vec[5:10]

; A three-element vector.

I = 25

print, vec[I - 1:I + 1]

; The same vector.

print, [vec[I - 1], vec[I], vec[I + 1]]

; Elements from vec[4] to the end, a 46-element (50-4) vector.

print, vec[4:*]

; Values of the elements with even subscripts in vec.

print, vec[0:*:2]

; The same as above, but in reverse order.

print, vec[-2:0:-2]

; Values of the elements with odd subscripts in vec:

print, vec[1:*:2]

; The same as above, but in reverse order.

print, vec[-1:0:-2]

; The fourth column of arr, a 1 column by 12 row vector.

print, arr[3, *]

; The first row of arr, a 10-element row vector. Note, the last

; dimension was removed because it was degenerate.

print, arr[*, 0]

; The nine-point neighborhood surrounding arr[X,Y], a 3 by 3 array.

X = 3

Y = 4

print, arr[X - 1:X + 1, Y - 1:Y + 1]

; Three columns of arr, a 3 by 12 subarray:

print, arr[3:5,*]

; The same three columns of arr, with the columns reversed:

print, arr[5:3:-1,*]

To insert the contents of an array called `A` into array `B`, starting at point `B`[13, 24], use the following statement:

B[13, 24] = A

If `A` is a 5-column by 6-row array, elements `B`[13:17, 24:29] are replaced by the contents of array `A`.

In the next example, a subarray is moved from one position to another:

B[100, 200] = B[200:300, 300:400]

A subarray of `B`, specifically the columns 200 to 300 and rows 300 to 400, is moved to columns 100 to 200 and rows 200 to 300, respectively.

Assuming the variable `B` is a 512 x 512-byte array, some examples are as follows:

; Store 1 in every element of the i-th row.

array[*, I] = 1

; Store 1 in every element of the j-th column.

array[J, *] = 1

; Zero all the rows of columns 200 through 220 of array.

array[200:220, *] = 0

; Zero the last 5 rows of columns 200 through 220 of array.

array[200:220, -5:-1] = 0

; Store the value 100 in all the elements of array.

array[*] = 100

## Avoid Using Range Subscripts for Assignment

It is possible to use range subscripts in an assignment statement, however, when possible, you should avoid using range subscripts in favor of using scalar or array subscripts. This type of assignment statement takes the following form:

Variable[Subscript_Range] = Expression

A subscript range specifies a beginning and ending subscripts, which are separated by the colon character. An ending subscript equal to the size of the dimension minus one can be written as *. For example, `arr[I:J]` denotes those points in the vector `arr` with subscripts between `I` and `J` inclusive. `I` must be less than or equal to `J` and greater than or equal to zero. See above for more details on subscript ranges.

When possible, you should avoid using range subscripts in favor of using scalar or array subscripts. In the following example, the array elements of `X` are inserted into array `A`. The slow way uses subscript ranges, specifying the insertion of `X` array elements into the 5th through 7th elements of `A`. The fast way uses a scalar subscript specifying the first element (the 5th) to be replaced with the elements of `A`.

A = INTARR(10)

X = [1,1,1]

PRINT, 'A = ', A

; Slow way:

t = SYSTIME(1) & FOR i=0L,100000 DO A[4:6] = X &

PRINT,'Slow way: ', SYSTIME(1)-t

PRINT, 'A = ', A

; Correct way is 4 times faster:

t = SYSTIME(1) & FOR i=0L,100000 DO A[4] = X &

PRINT, 'Fast way: ', SYSTIME(1)-t

PRINT, 'A = ', A

IDL prints:

A = 0 0 0 0 0 0 0 0 0 0

Slow way: 0.47000003

A = 0 0 0 0 1 1 1 0 0 0

Fast way: 0.12100005

A = 0 0 0 0 1 1 1 0 0 0

The statement `A[4] = X`, where `X` is a three-element array, causes IDL to start at index 4 of array `A`, and replace the next three elements in `A` with the elements in `X`. Because of the way it is implemented in IDL, `A[4] = X` is much more efficient than `A[4:6] = X`.