彷徨うITエンジニアの雑記

ITインフラ関連の雑記とか

Powershellメモ2

System.Array クラスで配列を作成する

  • 配列の型を指定しないと System.Array クラスで作成される。
  • 要素の追加は += 演算子を使用するが System.Array は固定長配列なので、追加処理の度に配列の再作成が実行されてめっちゃ遅い。

# System.Array クラスで空の配列を作成
> $array = @()
> $array.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

# += 演算子で要素を追加
> $array += 1
> $array += 2..5
> $array
1
2
3
4
5

# 配列を初期化
> $array.Clear()

# 初期値の入った配列を作成
> $array = @('a', 'b', 'c', 'd', 'e')

# Count プロパティで要素数を取得
> $array.Count
5

# インデックスを指定して要素を取得
> $array[2]
c

# インデックスを指定してスライスを取得
> $array[2..4]
c
d
e

# 配列に指定の要素が含まれるか判定
> $array.Contains("c")
True

# 配列をコピー
> $array_clone = $array.Clone()
> $array_clone
a
b
c
d
e

System.Collections.ArrayList クラスでコレクションを作成する

  • コレクションなので可変長の配列として使える
  • System.Array クラスより使えるメソッドが多い
  • 要素の追加は += も使えるが Add() メソッドの方が高速、ループで追加するような場合は後者を使ったほうが良い

# System.Collections.ArrayList クラスで空のコレクションを作成
> $array = New-Object System.Collections.ArrayList

# 以下でも同じ
> [System.Collections.ArrayList]$array = @()

> $array.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ArrayList                                System.Object

# Add() メソッドで要素を追加
> $null = $array.Add('one')
> $null = $array.Add('two')
> $null = $array.Add('three')
> $null = $array.Add('four')
> $null = $array.Add('five')
> $array
one
two
three
four
five

# $array.Add(1..5) は0番目の要素に 1,2,3,4,5 の配列が格納される

# Count プロパティで要素数を取得
> $array.Count
5

# インデックスを指定して要素を取得
> $array[2]
three

# インデックスを指定してスライスを取得
> $array[2..4]
three
four
five

# RemoveAt() メソッドで指定インデックスの要素を削除
> $array.RemoveAt(0)

# Remove() メソッドで一致する要素を削除
> $array.Remove('five')

# Insert() メソッドで指定インデックスに要素を挿入
> $array.Insert(0,'壱')
> $array
壱
two
three
four

# コレクションに指定の要素が含まれるか判定
> $array.Contains('壱')
True

# 昇順でソート
> $array.Sort()
> $array
four
three
two
壱

# 降順でソート
> $array.Reverse()
> $array
壱
two
three
four

# コレクションの複製
$array_clone = $array.Clone()

# コレクションを初期化
> $array.Clear()

Hashtable を Foreach-Object or foreach() したい

  • $hash | Foreach-Object {} して結構ハマる、良く忘れる

> $hash = @{ 'one' = '壱'; 'two' = '弐'; 'three' = '参'; 'four' = '肆'; 'five' = '伍' }
> $hash.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

> $hash

Name                           Value
----                           -----
one                            壱
three                          参
two                            弐
four                           肆
five                           伍


# 以下は想定通り動かない
> $hash | ForEach-Object { Write-Output ($_.Name + " is " + $_.Value) }
 is

# これなら動く
> $hash.Keys | ForEach-Object { Write-Output ($_ + " is " + $hash[$_]) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# GetEnumerator() で列挙子を返すと一番しっくりくる
> $hash.GetEnumerator() | ForEach-Object { Write-Output ($_.Name + " is " + $_.Value) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# foreach() なら以下のように
> foreach( $key in $hash.Keys ) { Write-Output ($key + " is " + $hash[$key]) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# GetEnumerator() を使う場合
> foreach( $obj in $hash.GetEnumerator() ) { Write-Output ($obj.Name + " is " + $obj.Value) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍