こんなにあった... F#ドキュメントには未掲載のArray関数

> * ※以下はF#のドキュメントが更新されれば不必要になるでしょう。
> * 前置きをスキップするときは「Arrayモジュールの未掲載関数」からお読みください。

F#はMicrosoftの[Don Syme](https://twitter.com/dsyme "https://twitter.com/dsyme")氏が開発したプログラミング言語で、命令型、オブジェクト指向、関数型の要素を併せ持つマルチパラダイム言語と[位置付けられています](https://msdn.microsoft.com/visualfsharpdocs/conceptual/visual-fsharp "https://msdn.microsoft.com/visualfsharpdocs/conceptual/visual-fsharp")。実装はオープンソースの[MITライセンス](https://github.com/fsharp/fsharp/blob/master/License.txt "https://github.com/fsharp/fsharp/blob/master/License.txt")のもと、[githubのリポジトリ](https://github.com/fsharp/fsharp "https://github.com/fsharp/fsharp")で公開されています。

実行環境は.NET Frameworkおよび.NET CoreやMonoといったマルチプラットフォームに対応していますが、サポート状況については各プラットフォームごとの情報を参照してください(「[F# の概要](https://docs.microsoft.com/ja-jp/dotnet/fsharp/get-started/index "https://docs.microsoft.com/ja-jp/dotnet/fsharp/get-started/index")」など)。

なお、ここで対象とするF#のバージョンは4.1([FSharp.Core](https://github.com/fsharp/fsharp/tree/master/src/fsharp/FSharp.Core "https://github.com/fsharp/fsharp/tree/master/src/fsharp/FSharp.Core") 4.4.1.0)とします。

# Arrayについて
`Array`は同じ型の複数の要素を同時に扱える(1次元)__配列__という型に対して実行できる関数が定義されたモジュールの名称です。配列の型名は`'T []`もしくは`array<'T>`(いずれも`'T`は要素の型)で表します。各要素は両端を`[|～|]`で囲んだ中に`;`(セミコロン)で区切って設定します。

配列の要素は定数や`for`で設定できます。`int`や`char`など`..`(範囲指定)で設定できる型もあります。

```fsharp:配列の要素を設定
[|'a'; 'b'; 'c'; 'd'; 'e'|]  // 定数による設定
[|for c in 'a'..'e' -> c|]   // forによる設定 ([|'a'; 'b'; 'c'; 'd'; 'e'|])
[|'a'..'e'|]    // 範囲指定による設定 ([|'a'; 'b'; 'c'; 'd'; 'e'|])
```

配列からは、特定の位置もしくは範囲にある要素のみを取り出せます。位置は先頭が`.[0]`でそれ以降`.[1], .[2], ...`と表します。範囲は`.[1..3]`などと表します。`[..3]`や`[2..]`のように範囲の始点や終点を明示しない場合は、それぞれ先頭や末尾とみなされます。

```fsharp:配列から特定の位置の要素を取り出す
let a = [|'a'..'e'|]  // [|'a'; 'b'; 'c'; 'd'; 'e'|]
a.[2]     // 'c'
a.[1..3]  // [|'b'; 'c'; 'd'|]
a.[2..]   // [|'c'; 'd'; 'e'|]
a.[..3]   // [|'a'; 'b'; 'c'; 'd'|]
```

配列の型は.NETの[System.Array](https://docs.microsoft.com/ja-jp/dotnet/api/system.array?view=netframework-4.7.1 "https://docs.microsoft.com/ja-jp/dotnet/api/system.array?view=netframework-4.7.1")クラスによるものなので、このクラスのプロパティやメソッドに対応しています。

```fsharp:配列の型
let a = [|'a'..'e'|]  // [|'a'; 'b'; 'c'; 'd'; 'e'|]

(* System.Arrayのプロパティやメソッドに対応 *)
a.Length  // 5
a.GetValue 2  // 'c'
System.Array.IndexOf(a, 'c')  // 2

(* リフレクションで型を確認 *)
a.GetType().FullName  // System.Char[]
a.GetType().BaseType.FullName  // System.Array
a.GetType().GetElementType().FullName  // System.Char
```

# Arrayモジュールの未掲載関数
F#では、`System.Array`クラスとは別に[Arrayモジュール](https://msdn.microsoft.com/visualfsharpdocs/conceptual/collections.array-module-%5bfsharp%5d "https://msdn.microsoft.com/visualfsharpdocs/conceptual/collections.array-module-%5bfsharp%5d")で多くの関数を定義済みです。ただ、[2017年8月18日更新分のドキュメント](https://msdn.microsoft.com/visualfsharpdocs/conceptual/collections.array-module-%5bfsharp%5d "https://msdn.microsoft.com/visualfsharpdocs/conceptual/collections.array-module-%5bfsharp%5d")には、定義されたすべての関数が掲載されているわけではありません。そこで、ここからはこのドキュメントに掲載されていない__未掲載関数__を紹介していきます。

## Array.chunkBySize 要素数 配列<br>int -> 'T [] -> 'T [] []
一次元配列の要素を指定された数ごとに区切った[ジャグ配列](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/jagged-arrays "https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/jagged-arrays")(配列の配列)を得られます。要素数は正の整数でないときは`System.ArgumentException`が発生します。要素数が配列より大きくても例外は発生しません。

```fsharp:Array.chunkBySize
Array.chunkBySize  3 [|0..7|]  // [|[|0; 1; 2|]; [|3; 4; 5|]; [|6; 7|]|] : int [] []
Array.chunkBySize  0 [|0..7|]  // 例外発生「System.ArgumentException: 入力は正である必要があります。」
Array.chunkBySize<int> 3 [||]  // [||] : int [] []
```

## Array.distinctBy 関数 配列<br>(('T -> 'U) -> 'T [] -> 'T []) when 'U : equality
配列の各要素を引数にして関数を実行し、その結果の配列から重複をなくしたものを得られます。要素のない空の配列でも例外は発生しません。

```fsharp:Array.distinctBy
Array.distinctBy (fun n -> n % 2) [|1; 3; 0; 2|]  // [|1; 0|]
Array.distinctBy<int, bool> (fun _ -> true) [||]  // [||] : int []
```

## Array.exactlyOne 要素1つだけの配列<br>'T [] -> 'T
要素が1つだけの配列から要素を取り出します。配列の要素が複数もしくは空のときは`System.ArgumentException`が発生します。逆のはたらきをする`Array.singleton`もあります。

```fsharp:Array.exactlyOne
Array.exactlyOne [|3|]      // 3 (Array.singletonとは逆)
Array.exactlyOne [|3; 2|]   // 例外発生「System.ArgumentException: 入力シーケンスに複数の要素が含まれています。」
Array.exactlyOne<int> [||]  // 例外発生「System.ArgumentException: 入力シーケンスが空でした。」

Array.singleton 3  // [|3|] (Array.exactlyOneとは逆)
```

## Array.except 配列1 配列2<br>(seq<'T> -> 'T [] -> 'T []) when 'T : equality
配列2の要素から配列1の要素を取り除いた配列を得られます。配列1はlist, seq, setにも対応します。どちらの配列が空でも例外は発生しません。

```fsharp:Array.except
Array.except [|2; 1|] [|3; 2; 5; 4; 1|]  // [|3; 5; 4|]  第1引数はlist, seq, setでも良い
Array.except<int> [||] [||]  // [||] : int []
```

## Array.findBack 関数 配列<br>('T -> bool) -> 'T [] -> 'T
配列の要素を引数にして関数を順次実行し、その結果(bool型)が最初に`true`となった要素を得られます。要素が見つからないときは`System.Collections.Generic.KeyNotFoundException`という例外が発生します。結果が`option`になる`Array.tryFindBack`や、配列の要素を先頭から順次判定していく[Array.find](https://msdn.microsoft.com/library/db6d920a-de19-4520-85a4-d83de77c1b33 "https://msdn.microsoft.com/library/db6d920a-de19-4520-85a4-d83de77c1b33")も定義されています。

```fsharp:Array.findBack
Array.findBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // 3
Array.findBack (fun n -> n % 2 = 1) [|0|]  // 例外発生「System.Collections.Generic.KeyNotFoundException」

Array.tryFindBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 3

Array.find        (fun n -> n % 2 = 1) [|1; 2; 3|]  // 1
```

## Array.findIndexBack<br>('T -> bool) -> 'T [] -> int
`Array.findBack`の結果がある要素の位置を得られます。要素が見つからないときは`System.Collections.Generic.KeyNotFoundException`が発生します。結果が`option`になる`Array.tryFindIndexBack`や、配列の要素を先頭から判定していく[Array.findIndex](https://msdn.microsoft.com/library/5ae3a8f9-7b8f-44ea-a740-d5700f4d899f "https://msdn.microsoft.com/library/5ae3a8f9-7b8f-44ea-a740-d5700f4d899f")もあります。

```fsharp:Array.findIndexBack
Array.findIndexBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // 2
Array.findIndexBack (fun n -> n % 2 = 1) [|0|]  // 例外発生「System.Collections.Generic.KeyNotFoundException」

Array.tryFindIndexBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 2
Array.findIndex (fun n -> n % 2 = 1) [|1; 2; 3|]  // 0
```

## Array.groupBy 関数 配列<br>(('T -> 'U) -> 'T [] -> ('U * 'T []) []) when 'U : equality
配列の要素を引数とする関数を順次実行し、その結果ごとに要素をグループ分けします。結果となる配列の要素は`(関数の結果, [|要素, ...|])`となります。引数の配列が空でも例外は発生しません。

```fsharp:Array.groupBy
Array.groupBy (fun n -> n % 3) [|0..7|]  // [|(0, [|0; 3; 6|]); (1, [|1; 4; 7|]); (2, [|2; 5|])|]
Array.groupBy (fun n -> n % 3) [||]  // [||] : (int * int []) []
```

## Array.head 配列<br>('T [] -> 'T)
配列の先頭の要素を得られます。配列要素が空のときは`System.ArgumentException`が発生します。結果が`option`になる`Array.tryHead`もあります。また、配列の先頭の要素だけをなくした配列を得る`Array.tail`や、配列の末尾の要素を得る`Array.last`や`Array.tryLast`もあります。

```fsharp:Array.head
Array.head [|3; 1; 2|]  // 3
Array.head<int> [||]    // 例外発生「System.ArgumentException: 入力配列が空でした。」

Array.tryHead [|3; 1; 2|]  // Some 3
Array.tryHead<int> [||]    // None

Array.tail [|3; 1; 2|]     // [|1; 2|]

Array.last [|3; 1; 2|]     // 2
Array.tryLast [|3; 1; 2|]  // Some 2
Array.tryLast<int> [||]    // None
```

## Array.indexed 配列<br>'T [] -> (int * 'T) []
配列の要素とその位置を`(位置, 要素)`という1つのタプルに収めた要素を持つ配列を得られます。配列の要素が空でも例外は発生しません。

```fsharp:Array.indexed
Array.indexed [|'a'..'c'|]  // [|(0, 'a'); (1, 'b'); (2, 'c')|]
Array.indexed<char> [||]    // [||] : (int * char) []
```

## Array.item 位置 配列<br>int -> 'T [] -> 'T
配列から指定した位置の要素を得られます。指定した位置に要素が存在しなければ`System.IndexOutOfRangeException`が発生します。結果が`option`になる`Array.tryItem`もあります。

```fsharp:Array.item
Array.item      2 [|'c'; 'a'; 'b'|]  // 'b'
Array.item<int> 1 [||]  // 例外発生「System.IndexOutOfRangeException: インデックスが配列の境界外です。」

Array.tryItem      2 [|'c'; 'a'; 'b'|]  // Some 'b'
Array.tryItem<int> 0 [||]  // None
```

## Array.last 配列<br>'T [] -> 'T
配列の末尾の要素を得られます。配列の要素が空のときは`System.ArgumentException`が発生します。結果が`option`になる`Array.tryLast`もあります。また、配列の先頭の要素を得られる`Array.head`や`Array.tryHead`もあります。

```fsharp:Array.last
Array.last      [|3; 1; 2|]  // 2
Array.last<int> [||]  // 例外発生「System.ArgumentException: 入力配列が空でした。」

Array.tryLast [|3; 1; 2|]  // Some 2
Array.tryLast<int> [||]    // None

Array.head    [|3; 1; 2|]  // 3
Array.tryHead [|3; 1; 2|]  // Some 3
```

## Array.map3 関数 配列1 配列2 配列3<br>('T -> 'U -> 'V -> 'W) -> 'T [] -> 'U [] -> 'V [] -> 'W []
同じ数の要素を持つ3つの配列のそれぞれから順次取り出した要素を引数とする関数を実行し、その結果を要素とする配列を得られます。それぞれの配列の要素の型が違っていても対応しますが、3つの配列の要素の数がどれか1つでも違っていると`System.ArgumentException`が発生します。

```fsharp:Array.map3
Array.map3 (fun x y z -> (x, y, z)) [|0..2|] [|'a'..'c'|] [|'$'..'&'|]
// [|(0, 'a', '$'); (1, 'b', '%'); (2, 'c', '&')|]
Array.map3 (fun x y z -> (x, y, z)) [|0..2|] [|'a'..'d'|] [|'$'..'&'|]
// 例外発生「System.ArgumentException: 配列の長さが異なります。」
```

## Array.mapFold 関数 初期値 配列<br>('T -> 'U -> 'V * 'T) -> 'T -> 'U [] -> 'V [] * 'T
初期値に対して配列の要素を関数で累積的に処理していった途中経過と最終的な結果をタプルで得られます。関数の引数を、初期値もしくは前回の処理結果と、配列の先頭から順次取り出される要素の2つとし、戻り値は`(最終結果のタプルの左側の要素, 次回関数実行時の第1引数)`とします。配列の要素を末尾から取り出す`Array.mapFoldBack`もありますが、引数の位置などに違いがありますので注意してください。

```fsharp:Array.mapFold
Array.mapFold (fun x y ->
  printfn "x = %2d, y = %1d, x * y = %3d" x y (x * y)
  (x, x * y)) 1 [|2..5|]
(* 途中経過 *)
x =  1, y = 2, x * y =   2
x =  2, y = 3, x * y =   6
x =  6, y = 4, x * y =  24
x = 24, y = 5, x * y = 120
(* 最終結果 *)
([|1; 2; 6; 24|], 120)

Array.mapFoldBack (fun x y -> (x, x * y)) [|2..5|] 1
// ([|2; 3; 4; 5|], 120)
```

## Array.mapFoldBack 関数 配列 初期値<br>('T -> 'U -> 'V * 'U) -> 'T [] -> 'U -> 'V [] * 'U

初期値に対して配列の要素を関数で累積的に処理していった途中経過と最終結果をタプルで得られます。関数の引数は、配列の末尾から順次取り出される要素と、初期値もしくは前回の処理結果の2つとし、戻り値は`(最終結果左側の配列の要素, 次回関数実行時の第2引数)`とします。最終結果の配列の要素は、先に関数から得られたものほど後に配置されます。配列の要素を先頭から順次取り出す`Array.mapFold`もありますが、引数の位置などに違いがありますので注意してください。

```fsharp:Array.mapFoldBack
Array.mapFoldBack (fun x y ->
  printfn "x = %1d, y = %2d, x * y = %3d" x y (x * y)
  (y, x * y)) [|2..5|] 1

(* 途中経過 *)
x = 5, y =  1, x * y =   5
x = 4, y =  5, x * y =  20
x = 3, y = 20, x * y =  60
x = 2, y = 60, x * y = 120

(* 最終結果 *)
([|60; 20; 5; 1|], 120)
```

## Array.pairwise配列<br>'T [] -> ('T * 'T) []
隣り合う要素どうしをタプル収めた要素を持つ配列を得られます。配列の要素が1つ以下のときの戻り値は空の配列となります。

```fsharp:Array.pairwise
Array.pairwise [|'a'..'d'|]  // [|('a', 'b'); ('b', 'c'); ('c', 'd')|]

Array.pairwise [|'a'|]       // [||] : (char * char) []
Array.pairwise<char> [||]    // [||] : (char * char) []
```

## Array.replicate 数値 要素<br>int -> 'T -> 'T []
同じ値の要素を複数持つ配列を得られます。数値が0以上の整数でなければは`System.ArgumentException`が発生します。

```fsharp:Array.replicate
Array.replicate  3 "F#"  // [|"F#"; "F#"; "F#"|]
Array.replicate -1 "F#"  // 例外発生「System.ArgumentException: 入力は負以外である必要があります。」
```

## Array.singleton 要素<br>'T -> 'T []
要素を1つだけ持つ配列を得られます。逆に要素が1つだけの配列から要素を取り出す`Array.exactlyOne`もあります。

```fsharp:Array.singleton
Array.singleton 3       // [|3|]
Array.exactlyOne [|3|]  // 3
```

## Array.skip 数値 配列<br>int -> 'T [] -> 'T []
先頭から指定した位置までの要素をなくした配列を得られます。数値が負の数でも例外は発生しません。逆に先頭から指定した位置までの要素を持つ配列を得られる`Array.take`もあります。

```fshap:Array.skip
Array.skip  2 [|'a'..'e'|]  // [|'c'; 'd'; 'e'|]
Array.skip -1 [|'a'..'e'|]  // [|'a'; 'b'; 'c'; 'd'; 'e'|]

Array.take 3 [|'a'..'e'|]  // [|'a'; 'b'; 'c'|]
```

## Array.skipWhile 関数 配列<br>('T -> bool) -> 'T [] -> 'T []
関数の戻り値がfalseとなる位置までの要素をなくした配列を得られます。逆にその位置までの要素を得られる`Array.takeWhile`もあります。

```fsharp:Array.skipWhile
Array.skipWhile (fun n -> n < 4) [|3; 2; 5; 4; 1|]  // [|5; 4; 1|]

Array.takeWhile (fun n -> n < 4) [|3; 2; 5; 4; 1|]  // [|3; 2|]
```

## Array.sortByDescending 関数 配列<br>(('T -> 'U) -> 'T [] -> 'T []) when 'U : comparison
配列の要素を引数とする関数を順次実行した結果をもとに要素を降順で並べ替えます。関数の結果は比較可能な値でなければなりません。他に配列の要素自体を並べ替える`Array.sortDescending`や、配列の並べ替えが昇順になる[Array.sortBy](https://msdn.microsoft.com/library/144498dc-091d-4575-a229-c0bcbd61426b "https://msdn.microsoft.com/library/144498dc-091d-4575-a229-c0bcbd61426b")もあります。

```fsharp:Array.sortByDescending
Array.sortByDescending (fun (x, _) -> x) [|(2, "dos"); (3, "tres"); (1, "uno")|]
// [|(3, "tres"); (2, "dos"); (1, "uno")|]

Array.sortDescending [|2; 3; 1; 5; 4|]
// [|5; 4; 3; 2; 1|]

Array.sortBy (fun (x, _) -> x) [|(2, "dos"); (3, "tres"); (1, "uno")|]
// [|(1, "uno"); (2, "dos"); (3, "tres")|]
```

## Array.sortDescending 配列<br>('T [] -> 'T []) when 'T : comparison
配列の要素を降順で並べ替えます。要素は比較可能な値でなければなりません。他に昇順で並べ替える[Array.sort](https://msdn.microsoft.com/library/c6679075-e7eb-463c-9be5-c89be140c312 "https://msdn.microsoft.com/library/c6679075-e7eb-463c-9be5-c89be140c312")や要素を引数にして関数を順次実行した値で並べ替える`Array.sortByDescending`もあります。

```fsharp:Array.sortDescending
Array.sortDescending [|2; 3; 1; 5; 4|]  // [|5; 4; 3; 2; 1|]

Array.sort [|2; 3; 1; 5; 4|]  // [|1; 2; 3; 4; 5|]

Array.sortByDescending (fun (x, _) -> x) [|(2, "dos"); (3, "tres"); (1, "uno")|]
// [|(3, "tres"); (2, "dos"); (1, "uno")|]
```

## Array.splitAt 位置 配列<br>int -> 'T [] -> 'T [] * 'T []
指定した要素の位置ので配列を2つに分け、それぞれを同じタプルに収めます。指定された位置の要素はタプルの右側の配列に含まれます。位置は0か正の整数に限られ、それ以外を指定すると`System.ArgumentException`が発生します。また、指定した位置が配列の長さ(要素の数)より大きいと`System.InvalidOperationException`が発生します。

```fsharp:Array.splitAt
Array.splitAt  3 [|'a'..'e'|]  // ([|'a'; 'b'; 'c'|], [|'d'; 'e'|])
Array.splitAt  0 [|'a'..'e'|]  // ([||], ([||], [|'a'; 'b'; 'c'; 'd'; 'e'|]))
Array.splitAt  5 [|'a'..'e'|]  // ([|'a'; 'b'; 'c'; 'd'; 'e'|], [||])

Array.splitAt -1 [|'a'..'e'|]  // 例外発生「System.ArgumentException: 入力は負以外である必要があります。」
Array.splitAt  6 [|'a'..'e'|]  // 例外発生「System.InvalidOperationException: 入力シーケンスには十分な数の要素がありません。」
```

## Array.splitInto 分割数 配列<br>int -> 'T [] -> 'T [] []
配列の要素を指定した数に等分します。結果は`'T [] []`になります。分割数が0のときは`System.ArgumentException`が発生します。分割数が配列の要素の数より大きくても例外は発生しません。

```fsharp:Array.splitInto
Array.splitInto 3 [|'a'..'e'|]  // [|[|'a'; 'b'|]; [|'c'; 'd'|]; [|'e'|]|] : char [] []
Array.splitInto 0 [|'a'..'e'|]  // 例外発生「System.ArgumentException: 入力は正である必要があります。」
Array.splitInto 3 [|'a'; 'b'|]  // [|[|'a'|]; [|'b'|]|]
```

## Array.tail 配列<br>'T [] -> 'T []
先頭の要素をなくした配列を得られます。配列の要素がないときは`System.ArgumentException`が発生します。逆に配列の先頭の要素だけを得られる`Array.head`もあります。

```fsharp:Array.tail
Array.tail [|3; 1; 2|]  // [|1; 2|]
Array.tail<int> [||]    // 例外発生「System.ArgumentException: 入力シーケンスには十分な数の要素がありません。」

Array.head [|3; 1; 2|]  // 3
```

## Array.take 要素数 配列<br>int -> 'T [] -> 'T []
先頭から指定された数だけの要素を持つ配列を得られます。要素数が負の数のときは`System.ArgumentException`が発生します。また、要素数が配列の長さより大きいときは`System.InvalidOperationException`が発生します。他に関数で判定した位置の要素を持つ配列を得られる`Array.takeWhile`や、逆に先頭から指定された数の要素をなくした配列を得られる`Array.skip`もあります。

```fsharp:Array.take
Array.take  3 [|'a'..'e'|]  // [|'a'; 'b'; 'c'|]
Array.take  0 [|'a'..'e'|]  // [||] : char []
Array.take -1 [|'a'..'e'|]  // 例外発生「System.ArgumentException: 入力は負以外である必要があります。」
Array.take  6 [|'a'..'e'|]  // 例外発生「System.InvalidOperationException: 入力シーケンスには十分な数の要素がありません。」

Array.takeWhile (fun n -> n < 4) [|3; 2; 5; 4; 1|]  // [|3; 2|]

Array.skip  3 [|'a'..'e'|]  // [|'d'; 'e'|]
```

## Array.takeWhile 関数 配列<br>('T -> bool) -> 'T [] -> 'T []
要素を引数とする関数を先頭から順次実行し、結果がtrueとなる要素を持つ配列を得られます。逆に結果がfalseとなる位置から末尾までの要素を持つ配列を得られる`Array.skipWhile`や、先頭から指定した位置までの要素を持つ配列を得られる`Array.take`もあります。

```fsharp:Array.takeWhile
Array.takeWhile (fun n -> n < 4) [|3; 2; 5; 4; 1|]  // [|3; 2|]

Array.skipWhile (fun n -> n < 4) [|3; 2; 5; 4; 1|]  // [|5; 4; 1|]

Array.take  3 [|3; 2; 5; 4; 1|]  // [|3; 2; 5|]
```

## Array.truncate 要素数 配列<br>int -> 'T [] -> 'T []
先頭から指定した数だけの要素を持つ配列を得られます。`Array.take`と違うのは、要素数に関連する例外が発生しないところです。

```fsharp:Array.truncate
Array.truncate  3 [|3; 2; 5; 4; 1|]  // [|3; 2; 5|]
Array.take      3 [|3; 2; 5; 4; 1|]  // [|3; 2; 5|]

(* 要素数が配列の長さより大きいとき *)
Array.truncate  6 [|3; 2; 5; 4; 1|]  // [|3; 2; 5; 4; 1|]
Array.take      6 [|3; 2; 5; 4; 1|]  // 例外発生「System.InvalidOperationException: 入力シーケンスには十分な数の要素がありません。」

(* 要素数が負の数のとき *)
Array.truncate -1 [|3; 2; 5; 4; 1|]  // [||] : int []
Array.take     -1 [|3; 2; 5; 4; 1|]  // 例外発生「System.ArgumentException: 入力は負以外である必要があります。」
```

## Array.tryFindBack 関数 配列<br>('T -> bool) -> 'T [] -> 'T option
末尾の要素から順次関数を実行し、結果が`true`となる要素を見つけます。結果は、見つかったら`Some 結果`、見つからなかったら`None`となります。結果が`option`ではない`Array.findBack`もあるほか、先頭の要素から順に関数を実行する[Array.tryFind](https://msdn.microsoft.com/library/7bd65f6c-df77-454c-ac3a-6f7baecec9d9 "https://msdn.microsoft.com/library/7bd65f6c-df77-454c-ac3a-6f7baecec9d9")や[Array.find](https://msdn.microsoft.com/library/db6d920a-de19-4520-85a4-d83de77c1b33 "https://msdn.microsoft.com/library/db6d920a-de19-4520-85a4-d83de77c1b33")もあります。

```fsharp:Array.tryFindBack
(* 結果が見つかったとき *)
Array.tryFindBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 3
Array.findBack    (fun n -> n % 2 = 1) [|1; 2; 3|]  // 3

(* 結果が見つからないとき *)
Array.tryFindBack (fun n -> n > 3) [|1; 2; 3|]  // None
Array.findBack    (fun n -> n > 3) [|1; 2; 3|]  // 例外発生「System.Collections.Generic.KeyNotFoundException」

Array.tryFind (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 1
Array.find    (fun n -> n % 2 = 1) [|1; 2; 3|]  // 1
```

## Array.tryFindIndexBack 関数 配列<br>('T -> bool) -> 'T [] -> int option
`Array.tryFindBack`の結果となる要素の位置を見つけます。結果は、見つかったら`Some 位置`、見つからなかったら`None`となります。要素の位置を先頭から見つける`Array.tryFindIndex`や、結果を`option`ではなく実際の値で得られる`Array.findIndexBack`もあります。

```fsharp:Array.tryFindIndexBack
Array.tryFindIndexBack (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 2

Array.tryFindIndex     (fun n -> n % 2 = 1) [|1; 2; 3|]  // Some 0

Array.findIndexBack    (fun n -> n % 2 = 1) [|1; 2; 3|]  // 2
```

## Array.tryHead 配列<br>'T [] -> 'T option
配列の先頭の要素を取り出します。要素が存在すれば`Some 要素`、要素が存在しなければ`None`となります。結果を`option`ではなく実際の値で得られる`Array.head`や、末尾の要素を得る`Array.tryLast`もあります。

```fsharp:Array.tryHead
(* 先頭の要素が存在するとき *)
Array.tryHead [|3; 1; 2|]  // Some 3
Array.head [|3; 1; 2|]  // 3

(* 先頭の要素が存在しないとき *)
Array.tryHead<int> [||]  // None
Array.head<int>    [||]  // 例外発生「System.ArgumentException: 入力配列が空でした。」

Array.tryLast [|3; 1; 2|]  // Some 2
```

## Array.tryItem 位置 配列<br>int -> 'T [] -> 'T option
指定した位置の要素を取り出します。要素が存在すれば`Some 要素`、存在しなければ`None`となります。結果が`option`ではなく要素で得られる`Array.item`もあります。

```fsharp:Array.tryItem
(* 指定した位置に要素が存在するとき *)
Array.tryItem 2 [|'c'; 'a'; 'b'|]  // Some 'b'
Array.item    2 [|'c'; 'a'; 'b'|]  // 'b'

(* 指定した位置に要素が存在しないとき *)
Array.tryItem 4 [|'c'; 'a'; 'b'|]  // None
Array.item    4 [|'c'; 'a'; 'b'|]  // 例外発生「System.IndexOutOfRangeException」
```

## Array.tryLast 配列<br>'T [] -> 'T option
配列の末尾の要素が得られたら`Some 要素`、得られなければ`None`となります。
結果が`option`ではなく要素自身となる`Array.last`もありますが、こちらは配列が空だと例外が発生します。また、配列の先頭の要素を得られる`Array.tryHead`もあります。

```fsharp:Array.tryLast
Array.tryLast [|3; 1; 2|]  // Some 2
Array.tryLast<int> [||]    // None

Array.last    [|3; 1; 2|]  // 2
Array.last<int> [||]       // 例外発生「System.ArgumentException: 入力配列が空でした。」

Array.tryHead [|3; 1; 2|]  // Some 3
```

## Array.unfold 関数 初期値<br>('T -> ('U * 'T) option) -> 'T -> 'U []
初期値を元に関数を累積的に実行して列をつくります。関数の引数は初期値および前回の結果とし、戻り値は、次回も関数を実行するときは`Some(結果となる配列の要素, 次回実行時の引数)`、関数の実行を終了するときは`None`とします。

```fsharp:Array.unfold
Array.unfold (fun n -> if n > 5 then None else Some (n, n + 1)) 1
// [|1; 2; 3; 4; 5|]

(* フィボナッチ数列の配列(Array.unfold) *)
let fibs n = Array.unfold (fun (x, y, z) ->
             if z > 0 then Some (x, (y, x + y, z - 1)) else None)
             <| (1, 1, n)
// fibs 10 = [|1; 1; 2; 3; 5; 8; 13; 21; 34; 55|]

(* フィボナッチ数(Array.fold) *)
let fib n = fst <| Array.fold (fun (x, y) _ -> (x + y, x)) (0, 1) [|1..n|]
// fib 10 = 55
```

## Array.where 関数 配列<br>('T -> bool) -> 'T [] -> 'T []
[Array.filter](https://msdn.microsoft.com/library/b885b214-47fc-4639-9664-b8c183a39ede "https://msdn.microsoft.com/library/b885b214-47fc-4639-9664-b8c183a39ede")と同様に、配列の各要素で実行した関数の結果が`true`となるものをすべて取り出します。`Array.find`では最初に`true`となる要素のみとなるのが違います。

```fsharp:Array.where
Array.where  (fun n -> n % 2 = 0) [|1..5|]  // [|2; 4|]
Array.filter (fun n -> n % 2 = 0) [|1..5|]  // [|2; 4|]

Array.find   (fun n -> n % 2 = 0) [|1..5|]  // 2
```

## Array.windowed 要素数 配列<br>int -> 'T [] -> 'T [] []
指定した要素数だけ位置が連続する配列を要素とする[ジャグ配列](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/jagged-arrays "https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/jagged-arrays")を得られます。要素数が正の整数でないときは`System.ArgumentException`が発生します。また、要素数が配列の要素の数を上回ると結果の配列は空となります。

要素数を2に指定すると結果が`Array.pairwise`と似てきますが、要素がタプルか配列かが違います。`Array.chunkBySize`との違いは、ただ配列の要素を区切るのではなく、先頭の要素から順次要素数だけ連続する要素を1つの配列にまとめているところです。

```fsharp:Array.windowed
Array.windowed 3 [|'a'..'e'|]  // [|[|'a'; 'b'; 'c'|]; [|'b'; 'c'; 'd'|]; [|'c'; 'd'; 'e'|]|]
Array.windowed 0 [|'a'..'e'|]  // 例外発生「System.ArgumentException: 入力は正である必要があります。」
Array.windowed 6 [|'a'..'e'|]  // [||] : char [] []

(* windowedとpairwiseとの違い *)
Array.windowed 2 [|'a'..'e'|]  // [|[|'a'; 'b'|]; [|'b'; 'c'|]; [|'c'; 'd'|]; [|'d'; 'e'|]|]
Array.pairwise   [|'a'..'e'|]  // [|('a', 'b'); ('b', 'c'); ('c', 'd'); ('d', 'e')|]

(* windowedとchunBySizeとの違い *)
Array.windowed    3 [|'a'..'e'|]  // [|[|'a'; 'b'; 'c'|]; [|'b'; 'c'; 'd'|]; [|'c'; 'd'; 'e'|]|]
Array.chunkBySize 3 [|'a'..'e'|]  // [|[|'a'; 'b'; 'c'|]; [|'d'; 'e'|]|]
```

## Array.allPairs 配列1 配列2<br>'T [] -> 'U [] -> ('T * 'U) []
配列1と配列2の各要素のすべての組み合わせをタプルの要素とする配列を得られます。結果となる配列の長さが膨大になる可能性があるため、引数の配列の長さに注意してください。また、引数の配列のどちらかが空のときは結果の配列も空になります。

```fsharp:Array.allPairs
Array.allPairs   [|'a'; 'b'; 'c'|] [|1; 2|]  // [|('a', 1); ('a', 2); ('b', 1); ('b', 2); ('c', 1); ('c', 2)|]
Array.allPairs<char, int> [|'a'; 'b'|] [||]  // [||] : (char * int) []
```

---
ドキュメントが更新されたら、このページは不要になると思いますが、その時までご覧になった方々の参考になればと思います。