9. Arrays
9.1 Introduction
PowerShell supports arrays of one or more dimensions with each dimension having zero or more
elements. Within a dimension, elements are numbered in ascending integer order starting at zero.
Any individual element can be accessed via the array subscript operator []
(§7.1.4). The
number of dimensions in an array is called its rank.
An element can contain a value of any type including an array type. An array having one or more elements whose values are of any array type is called a jagged array. A multidimensional array has multiple dimensions, in which case, the number of elements in each row of a dimension is the same. An element of a jagged array may contain a multidimensional array, and vice versa.
Multidimensional arrays are stored in row-major order. The number of elements in an array is called
that array's length, which is fixed when the array is created. As such, the elements in a
1-dimensional array A having length N can be accessed (i.e., subscripted) using the
expressions A[0], A[1], ..., A[N-1]
. The elements in a 2-dimensional array B having M rows,
with each row having N columns, can be accessed using the expressions
B[0,0], B[0,1], ..., B[0,N-1], B[1,0], B[1,1], ..., B[1,N-1], ..., B[M-1,0], B[M-1,1], ..., B[M-1,N-1]
.
And so on for arrays with three or more dimensions.
By default, an array is polymorphic; i.e., its elements do not need to all have the same type. For example,
$items = 10,"blue",12.54e3,16.30D # 1-D array of length 4
$items[1] = -2.345
$items[2] = "green"
$a = New-Object 'object[,]' 2,2 # 2-D array of length 4
$a[0,0] = 10
$a[0,1] = $false
$a[1,0] = "red"
$a[1,1] = $null
A 1-dimensional array has type type[]
, a 2-dimensional array has type type[,]
, a 3-dimensional
array has type type[,,]
, and so on, where type is object for an unconstrained type array, or the
constrained type for a constrained array (§9.4).
All array types are derived from the type Array (§4.3.2).
9.2 Array creation
An array is created via an array creation expression, which has the following forms: unary comma operator (§7.2.1) ,array-expression (§7.1.7), binary comma operator (§7.3), range operator (§7.4), or New-Object cmdlet.
Here are some examples of array creation and usage:
$values = 10, 20, 30
for ($i = 0; $i -lt $values.Length; ++$i) {
"`$values[$i] = $($values[$i])"
}
$x = , 10 # x refers to an array of length 1
$x = @(10) # x refers to an array of length 1
$x = @() # x refers to an array of length 0
$a = New-Object 'object[,]' 2, 2 # create a 2x2 array of anything
$a[0, 0] = 10 # set to an int value
$a[0, 1] = $false # set to a boolean value
$a[1, 0] = "red" # set to a string value
$a[1, 1] = 10.50D # set to a decimal value
foreach ($e in $a) { # enumerate over the whole array
$e
}
The following is written to the pipeline:
$values[0] = 10
$values[1] = 20
$values[2] = 30
10
False
red
10.50
The default initial value of any element not explicitly initialized is the default value for that
element's type (that is, $false
, zero, or $null
).
9.3 Array concatenation
Arrays of arbitrary type and length can be concatenated via the +
and +=
operators, both of
which result in the creation of a new unconstrained 1-dimensional array. The existing arrays are
unchanged. See §7.7.3 for more information, and §9.4 for a discussion of adding to an array
of constrained type.
9.4 Constraining element types
A 1-dimensional array can be created so that it is type-constrained by prefixing the array-creation expression with an array type cast. For example,
$a = [int[]](1,2,3,4) # constrained to int
$a[1] = "abc" # implementation-defined behavior
$a += 1.23 # new array is unconstrained
The syntax for creating a multidimensional array requires the specification of a type, and that type
becomes the constraint type for that array. However, by specifying type object[]
, there really is
no constraint as a value of any type can be assigned to an element of an array of that type.
Concatenating two arrays (§7.7.3) always results in a new array that is unconstrained even if both arrays are constrained by the same type. For example,
$a = [int[]](1,2,3) # constrained to int
$b = [int[]](10,20) # constrained to int
$c = $a + $b # constraint not preserved
$c = [int[]]($a + $b) # result explicitly constrained to int
9.5 Arrays as reference types
As array types are reference types, a variable designating an array can be made to refer to any array of any rank, length, and element type. For example,
$a = 10,20 # $a refers to an array of length 2
$a = 10,20,30 # $a refers to a different array, of length 3
$a = "red",10.6 # $a refers to a different array, of length 2
$a = New-Object 'int[,]' 2,3 # $a refers to an array of rank 2
Assignment of an array involves a shallow copy; that is, the variable assigned to refers to the same array, no copy of the array is made. For example,
$a = 10,20,30
">$a<"
$b = $a # make $b refer to the same array as $a
">$b<"
$a[0] = 6 # change value of [0] via $a
">$a<"
">$b<" # change is reflected in $b
$b += 40 # make $b refer to a new array
$a[0] = 8 # change value of [0] via $a
">$a<"
">$b<" # change is not reflected in $b
The following is written to the pipeline:
>10 20 30<
>10 20 30<
>6 20 30<
>6 20 30<
>8 20 30<
>6 20 30 40<
9.6 Arrays as array elements
Any element of an array can itself be an array. For example,
$colors = "red", "blue", "green"
$list = $colors, (,7), (1.2, "yes") # parens in (,7) are redundant; they
# are intended to aid readability
"`$list refers to an array of length $($list.Length)"
">$($list[1][0])<"
">$($list[2][1])<"
The following is written to the pipeline:
$list refers to an array of length 3
>7<
>yes<
$list[1]
refers to an array of 1 element, the integer 7, which is accessed via $list[1][0]
, as
shown. Compare this with the following subtly different case:
$list = $colors, 7, (1.2, "yes") # 7 has no prefix comma
">$($list[1])<"
Here, $list[1]
refers to a scalar, the integer 7, which is accessed via $list[1]
.
Consider the following example,
$x = [string[]]("red","green")
$y = 12.5, $true, "blue"
$a = New-Object 'object[,]' 2,2
$a[0,0] = $x # element is an array of 2 strings
$a[0,1] = 20 # element is an int
$a[1,0] = $y # element is an array of 3 objects
$a[1,1] = [int[]](92,93) # element is an array of 2 ints
9.7 Negative subscripting
This is discussed in §7.1.4.1.
9.8 Bounds checking
This is discussed in §7.1.4.1.
9.9 Array slices
An array slice is an unconstrained 1-dimensional array whose elements are copies of zero or more
elements from a collection. An array slice is created via the subscript operator []
(§7.1.4.5).
9.10 Copying an array
A contiguous set of elements can be copied from one array to another using the method
[Array]::Copy
. For example,
$a = [int[]](10,20,30)
$b = [int[]](0,1,2,3,4,5)
[Array]::Copy($a, $b, 2) # $a[0]->$b[0],
$a[1]->$b[1]
[Array]::Copy($a, 1, $b, 3, 2) # $a[1]->$b[3],
$a[2]->$b[4]
9.11 Enumerating over an array
Although it is possible to loop through an array accessing each of its elements via the subscript operator, we can enumerate over that array's elements using the foreach statement. For a multidimensional array, the elements are processed in row-major order. For example,
$a = 10, 53, 16, -43
foreach ($elem in $a) {
# do something with element via $elem
}
foreach ($elem in -5..5) {
# do something with element via $elem
}
$a = New-Object 'int[,]' 3, 2
foreach ($elem in $a) {
# do something with element via $elem
}
9.12 Multidimensional array flattening
Some operations on a multidimensional array (such as replication (§7.6.3) and concatenation (§7.7.3)) require that array to be flattened; that is, to be turned into a 1-dimensional array of unconstrained type. The resulting array takes on all the elements in row-major order.
Consider the following example:
$a = "red",$true
$b = (New-Object 'int[,]' 2,2)
$b[0,0] = 10
$b[0,1] = 20
$b[1,0] = 30
$b[1,1] = 40
$c = $a + $b
The array designated by $c
contains the elements "red", $true
, 10, 20, 30, and 40.