目次

概要

ここでは、配列について説明します。

PowerShell では、2つのコマンドをパイプラインで繋ぐと、 オブジェクトの配列として入出力の受け渡しが行われます。

配列

PowerShell には , を使う方法と @ を使う方法、 2種類の配列の作り方があります。 (あと、整数限定で .. 演算子というのもあります。)

, 演算子

まず、複数のオブジェクトを , を使って並べると、 並べたオブジェクトを要素とする配列ができます。 また、配列の要素には [] を使ってアクセスします(インデックスは 0 から始まる)。

>  $a = 1,2,3,4
>  $a
1
2
3
4
>  $a[0]
# ↓ PowerShell の配列は 0 ベース
1
>  $a.Length
4

,1 というように、単項演算子的にも使えます。 (長さ1の配列になる。)

>  $a = ,1
>  $a.Length
1
>  $a[0]
1

この , 演算子はかなり結合順位が高いので注意。

>  1, 1+1, 1
# ↓ 要するに (1, 1) + (1, 1)
1
1
1
1

@()

もう1つは @ を使う方法で、 @(1, 2, 3) というように、@ に続けて () を書くと配列が作れます。 こちらの場合、区切り文字は ; (要するに、コマンドの区切り)も使えます。 あと、@() で空(長さ0)の配列も作れます。

>  @(1; 2; 3)
1
2
3
>  $a = @()
>  $a.GetType().Name
Object[]
>  $a.Length
0

この記法では、複数のコマンドや式の出力・計算結果を繋いで配列にすることもできます。 (この場合、区切り文字は ; でないと駄目。)

>  $a = @(pwd; 1 + 1)
>  $a[0]

Path
----
C:\Users\Public

>  $a[1]
2

.. 演算子

あと、整数に限れば、1..3 (1, 2, 3 と同じ意味)というように、 .. を使って一定範囲の連続した数値列を作ることができます。

> 1..3
1
2
3

結合の優先順位が , 演算子より下なようで、 「1..3, 5」と言うような書き方はエラーになります。 (@ を使って、@(1..3; 5) という書き方なら OK。)

> 1..3,5
"System.Object[]" を "System.Int32" に変換できません。
> @(1..3; 5)
1
2
3
5

.. を使った配列と , を使った配列を併用したければ、 後述する配列結合の + 演算子を使う手もあります。

> 1..3 + 5, 7
1
2
3
5
7

末尾からのアクセス

配列のインデックスに負の数 i を指定すると、 配列の末尾から i 番目の要素にアクセスできます。

> $a = 1,2,3
> $a[-1]
3
> $a[-2]
2
> $a[-3]
1

範囲外へのアクセス

配列に対して、範囲外にアクセスした場合、 読み出しなら null 値を返すだけで、 書き込みはエラーになります。

>  $a = @()
>  $a[0]
# ↓ null を返すだけ
>  $a[0] = 1
インデックス '0' が範囲外のため、配列の代入が失敗しました。

配列の連結

配列は + 演算子で連結することができます。

>  $a = 1,2
>  $b = 3,4
>  $c = $a + $b
>  $c.Length
4
>  $c
1
2
3
4
  • が配列の結合なので、 += は要素の追加になります。
> $a = 1,2,3
> $a += 10
> $a
1
2
3
10

, 演算子でも連結されたように見えたりしますが、 実際には多次元配列になります。

>  $a = 1,2
>  $b = 3,4
>  $c = $a, $b
>  $c
1
2
3
4
>  $c[0]
1
2
>  $c[1]
3
4
>  $c.Length
2

部分取得

以下のような記法で、 配列の一部分を抜き出すことができます。

>  $a = 1,2,3,4,5,6
>  $a[1,3,5]
2
4
6
>  $a[0..2]
1
2
3
> $a[0..2 + 4]
1
2
3
5

条件演算子

-contains 演算子で、配列の中に要素が含まれているかどうかを調べることができます。

>  $a = 1,3,5
>  $a -contains 1
True
>  $a -contains 2
False

また、 配列に対して、-eq や -lt などの比較演算子を使うことで、 特定条件を満たす要素だけを抜き出すことができます。

>  $a = 1,2,3,9,8,7,4,5,6
>  $a -lt 5
1
2
3
4
>  $a -gt 5
9
8
7
6

複数の変数の同時代入

$a, $b, $c = 1, 2, 3 というように、 左辺も , で繋ぐことで、複数の変数に同時に値を代入することができます。 左右で要素の数が違う場合、 最後の1変数が配列になったり、 足りない分が null 値になったりします。

>  $a, $b, $c = 1,2,3,4,5
>  $a
1
>  $b
2
>  $c
3
4
5
>  $a, $b, $c = 1,2
>  $a
1
>  $b
2
>  $c

連想配列

@() で普通の配列を作るのに対して、 @{} で連想配列を作れます。 (型は System.Collections.Hashtable になります。)

(連想配列は、 Perl でいうところのハッシュ、 C++ の map、 C# の Hashtable や Dictionary のことで、 a["test"] = 1 とかいうように、 数字以外のインデックスを持てる配列です。)

$a = @{} という風にして空の連想配列を作って、 後から要素を作ることもできますし、 $a = @{x = 1} というように初期化のときに要素を作ることもできます。

要素へのアクセスには2通りの方法があります。 1つは、配列らしく、$a["x"] と書く記法で、 もう1つは $a.x というようにあたかもメンバー変数にアクセスするかのような記法です。

>  $a = @{}
>  $a.x = 1
>  $a.x
1
>  $a = @{x = 1; y = 2; z = 3}
>  $a.x
1
>  $a.y
2
>  $a.z
3
>  $a["x"] = 1
>  $a["x"]
1

ちなみに、連想配列のキーは、別に文字列である必要はありません。

>  $a[1.234] = 1
>  $a[ [DateTime]::Now ] = 2
>  $a[1024] = 3
>  $a[ [int] ] = 4

すごく気持ち悪いですけど、 . を使う方でも任意の型のキーを参照できます。

>  $a[[int]] = 2
>  $a.[int]
2
>  $b = [DateTime]::Now
>  $a[$b] = 6
>  $a.$b
6
>  $a[2] = 3
>  $a.(1 + 1)
3
>  $a.x = 9
>  $a."x"
9

更新履歴

ブログ