- ※以下はF#のドキュメントが更新されれば不必要になるでしょう。
- 前置きをスキップするときは「Arrayモジュールの未掲載関数」からお読みください。
F#はMicrosoftのDon Syme氏が開発したプログラミング言語で、命令型、オブジェクト指向、関数型の要素を併せ持つマルチパラダイム言語と位置付けられています。実装はオープンソースのMITライセンスのもと、githubのリポジトリで公開されています。
実行環境は.NET Frameworkおよび.NET CoreやMonoといったマルチプラットフォームに対応していますが、サポート状況については各プラットフォームごとの情報を参照してください(「F# の概要」など)。
なお、ここで対象とするF#のバージョンは4.1(FSharp.Core 4.4.1.0)とします。
Arrayについて
Array
は同じ型の複数の要素を同時に扱える(1次元)__配列__という型に対して実行できる関数が定義されたモジュールの名称です。配列の型名は'T []
もしくはarray<'T>
(いずれも'T
は要素の型)で表します。各要素は両端を[|~|]
で囲んだ中に;
(セミコロン)で区切って設定します。
配列の要素は定数やfor
で設定できます。int
やchar
など..
(範囲指定)で設定できる型もあります。
[|'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..]
のように範囲の始点や終点を明示しない場合は、それぞれ先頭や末尾とみなされます。
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クラスによるものなので、このクラスのプロパティやメソッドに対応しています。
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モジュールで多くの関数を定義済みです。ただ、2017年8月18日更新分のドキュメントには、定義されたすべての関数が掲載されているわけではありません。そこで、ここからはこのドキュメントに掲載されていない__未掲載関数__を紹介していきます。
Array.chunkBySize 要素数 配列
int -> 'T [] -> 'T [] []
一次元配列の要素を指定された数ごとに区切ったジャグ配列(配列の配列)を得られます。要素数は正の整数でないときはSystem.ArgumentException
が発生します。要素数が配列より大きくても例外は発生しません。
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 関数 配列
(('T -> 'U) -> 'T [] -> 'T []) when 'U : equality
配列の各要素を引数にして関数を実行し、その結果の配列から重複をなくしたものを得られます。要素のない空の配列でも例外は発生しません。
Array.distinctBy (fun n -> n % 2) [|1; 3; 0; 2|] // [|1; 0|]
Array.distinctBy<int, bool> (fun _ -> true) [||] // [||] : int []
Array.exactlyOne 要素1つだけの配列
'T [] -> 'T
要素が1つだけの配列から要素を取り出します。配列の要素が複数もしくは空のときはSystem.ArgumentException
が発生します。逆のはたらきをするArray.singleton
もあります。
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
(seq<'T> -> 'T [] -> 'T []) when 'T : equality
配列2の要素から配列1の要素を取り除いた配列を得られます。配列1はlist, seq, setにも対応します。どちらの配列が空でも例外は発生しません。
Array.except [|2; 1|] [|3; 2; 5; 4; 1|] // [|3; 5; 4|] 第1引数はlist, seq, setでも良い
Array.except<int> [||] [||] // [||] : int []
Array.findBack 関数 配列
('T -> bool) -> 'T [] -> 'T
配列の要素を引数にして関数を順次実行し、その結果(bool型)が最初にtrue
となった要素を得られます。要素が見つからないときはSystem.Collections.Generic.KeyNotFoundException
という例外が発生します。結果がoption
になるArray.tryFindBack
や、配列の要素を先頭から順次判定していくArray.findも定義されています。
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
('T -> bool) -> 'T [] -> int
Array.findBack
の結果がある要素の位置を得られます。要素が見つからないときはSystem.Collections.Generic.KeyNotFoundException
が発生します。結果がoption
になるArray.tryFindIndexBack
や、配列の要素を先頭から判定していくArray.findIndexもあります。
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 関数 配列
(('T -> 'U) -> 'T [] -> ('U * 'T []) []) when 'U : equality
配列の要素を引数とする関数を順次実行し、その結果ごとに要素をグループ分けします。結果となる配列の要素は(関数の結果, [|要素, ...|])
となります。引数の配列が空でも例外は発生しません。
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 配列
('T [] -> 'T)
配列の先頭の要素を得られます。配列要素が空のときはSystem.ArgumentException
が発生します。結果がoption
になるArray.tryHead
もあります。また、配列の先頭の要素だけをなくした配列を得るArray.tail
や、配列の末尾の要素を得るArray.last
やArray.tryLast
もあります。
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 配列
'T [] -> (int * 'T) []
配列の要素とその位置を(位置, 要素)
という1つのタプルに収めた要素を持つ配列を得られます。配列の要素が空でも例外は発生しません。
Array.indexed [|'a'..'c'|] // [|(0, 'a'); (1, 'b'); (2, 'c')|]
Array.indexed<char> [||] // [||] : (int * char) []
Array.item 位置 配列
int -> 'T [] -> 'T
配列から指定した位置の要素を得られます。指定した位置に要素が存在しなければSystem.IndexOutOfRangeException
が発生します。結果がoption
になるArray.tryItem
もあります。
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 配列
'T [] -> 'T
配列の末尾の要素を得られます。配列の要素が空のときはSystem.ArgumentException
が発生します。結果がoption
になるArray.tryLast
もあります。また、配列の先頭の要素を得られるArray.head
やArray.tryHead
もあります。
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
('T -> 'U -> 'V -> 'W) -> 'T [] -> 'U [] -> 'V [] -> 'W []
同じ数の要素を持つ3つの配列のそれぞれから順次取り出した要素を引数とする関数を実行し、その結果を要素とする配列を得られます。それぞれの配列の要素の型が違っていても対応しますが、3つの配列の要素の数がどれか1つでも違っているとSystem.ArgumentException
が発生します。
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 関数 初期値 配列
('T -> 'U -> 'V * 'T) -> 'T -> 'U [] -> 'V [] * 'T
初期値に対して配列の要素を関数で累積的に処理していった途中経過と最終的な結果をタプルで得られます。関数の引数を、初期値もしくは前回の処理結果と、配列の先頭から順次取り出される要素の2つとし、戻り値は(最終結果のタプルの左側の要素, 次回関数実行時の第1引数)
とします。配列の要素を末尾から取り出すArray.mapFoldBack
もありますが、引数の位置などに違いがありますので注意してください。
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 関数 配列 初期値
('T -> 'U -> 'V * 'U) -> 'T [] -> 'U -> 'V [] * 'U
初期値に対して配列の要素を関数で累積的に処理していった途中経過と最終結果をタプルで得られます。関数の引数は、配列の末尾から順次取り出される要素と、初期値もしくは前回の処理結果の2つとし、戻り値は(最終結果左側の配列の要素, 次回関数実行時の第2引数)
とします。最終結果の配列の要素は、先に関数から得られたものほど後に配置されます。配列の要素を先頭から順次取り出すArray.mapFold
もありますが、引数の位置などに違いがありますので注意してください。
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配列
'T [] -> ('T * 'T) []
隣り合う要素どうしをタプル収めた要素を持つ配列を得られます。配列の要素が1つ以下のときの戻り値は空の配列となります。
Array.pairwise [|'a'..'d'|] // [|('a', 'b'); ('b', 'c'); ('c', 'd')|]
Array.pairwise [|'a'|] // [||] : (char * char) []
Array.pairwise<char> [||] // [||] : (char * char) []
Array.replicate 数値 要素
int -> 'T -> 'T []
同じ値の要素を複数持つ配列を得られます。数値が0以上の整数でなければはSystem.ArgumentException
が発生します。
Array.replicate 3 "F#" // [|"F#"; "F#"; "F#"|]
Array.replicate -1 "F#" // 例外発生「System.ArgumentException: 入力は負以外である必要があります。」
Array.singleton 要素
'T -> 'T []
要素を1つだけ持つ配列を得られます。逆に要素が1つだけの配列から要素を取り出すArray.exactlyOne
もあります。
Array.singleton 3 // [|3|]
Array.exactlyOne [|3|] // 3
Array.skip 数値 配列
int -> 'T [] -> 'T []
先頭から指定した位置までの要素をなくした配列を得られます。数値が負の数でも例外は発生しません。逆に先頭から指定した位置までの要素を持つ配列を得られるArray.take
もあります。
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 関数 配列
('T -> bool) -> 'T [] -> 'T []
関数の戻り値がfalseとなる位置までの要素をなくした配列を得られます。逆にその位置までの要素を得られるArray.takeWhile
もあります。
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 関数 配列
(('T -> 'U) -> 'T [] -> 'T []) when 'U : comparison
配列の要素を引数とする関数を順次実行した結果をもとに要素を降順で並べ替えます。関数の結果は比較可能な値でなければなりません。他に配列の要素自体を並べ替えるArray.sortDescending
や、配列の並べ替えが昇順になるArray.sortByもあります。
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 配列
('T [] -> 'T []) when 'T : comparison
配列の要素を降順で並べ替えます。要素は比較可能な値でなければなりません。他に昇順で並べ替えるArray.sortや要素を引数にして関数を順次実行した値で並べ替えるArray.sortByDescending
もあります。
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 位置 配列
int -> 'T [] -> 'T [] * 'T []
指定した要素の位置ので配列を2つに分け、それぞれを同じタプルに収めます。指定された位置の要素はタプルの右側の配列に含まれます。位置は0か正の整数に限られ、それ以外を指定するとSystem.ArgumentException
が発生します。また、指定した位置が配列の長さ(要素の数)より大きいとSystem.InvalidOperationException
が発生します。
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 分割数 配列
int -> 'T [] -> 'T [] []
配列の要素を指定した数に等分します。結果は'T [] []
になります。分割数が0のときはSystem.ArgumentException
が発生します。分割数が配列の要素の数より大きくても例外は発生しません。
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 配列
'T [] -> 'T []
先頭の要素をなくした配列を得られます。配列の要素がないときはSystem.ArgumentException
が発生します。逆に配列の先頭の要素だけを得られるArray.head
もあります。
Array.tail [|3; 1; 2|] // [|1; 2|]
Array.tail<int> [||] // 例外発生「System.ArgumentException: 入力シーケンスには十分な数の要素がありません。」
Array.head [|3; 1; 2|] // 3
Array.take 要素数 配列
int -> 'T [] -> 'T []
先頭から指定された数だけの要素を持つ配列を得られます。要素数が負の数のときはSystem.ArgumentException
が発生します。また、要素数が配列の長さより大きいときはSystem.InvalidOperationException
が発生します。他に関数で判定した位置の要素を持つ配列を得られるArray.takeWhile
や、逆に先頭から指定された数の要素をなくした配列を得られるArray.skip
もあります。
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 関数 配列
('T -> bool) -> 'T [] -> 'T []
要素を引数とする関数を先頭から順次実行し、結果がtrueとなる要素を持つ配列を得られます。逆に結果がfalseとなる位置から末尾までの要素を持つ配列を得られるArray.skipWhile
や、先頭から指定した位置までの要素を持つ配列を得られるArray.take
もあります。
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 要素数 配列
int -> 'T [] -> 'T []
先頭から指定した数だけの要素を持つ配列を得られます。Array.take
と違うのは、要素数に関連する例外が発生しないところです。
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 関数 配列
('T -> bool) -> 'T [] -> 'T option
末尾の要素から順次関数を実行し、結果がtrue
となる要素を見つけます。結果は、見つかったらSome 結果
、見つからなかったらNone
となります。結果がoption
ではないArray.findBack
もあるほか、先頭の要素から順に関数を実行するArray.tryFindやArray.findもあります。
(* 結果が見つかったとき *)
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 関数 配列
('T -> bool) -> 'T [] -> int option
Array.tryFindBack
の結果となる要素の位置を見つけます。結果は、見つかったらSome 位置
、見つからなかったらNone
となります。要素の位置を先頭から見つけるArray.tryFindIndex
や、結果をoption
ではなく実際の値で得られるArray.findIndexBack
もあります。
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 配列
'T [] -> 'T option
配列の先頭の要素を取り出します。要素が存在すればSome 要素
、要素が存在しなければNone
となります。結果をoption
ではなく実際の値で得られるArray.head
や、末尾の要素を得るArray.tryLast
もあります。
(* 先頭の要素が存在するとき *)
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 位置 配列
int -> 'T [] -> 'T option
指定した位置の要素を取り出します。要素が存在すればSome 要素
、存在しなければNone
となります。結果がoption
ではなく要素で得られるArray.item
もあります。
(* 指定した位置に要素が存在するとき *)
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 配列
'T [] -> 'T option
配列の末尾の要素が得られたらSome 要素
、得られなければNone
となります。
結果がoption
ではなく要素自身となるArray.last
もありますが、こちらは配列が空だと例外が発生します。また、配列の先頭の要素を得られるArray.tryHead
もあります。
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 関数 初期値
('T -> ('U * 'T) option) -> 'T -> 'U []
初期値を元に関数を累積的に実行して列をつくります。関数の引数は初期値および前回の結果とし、戻り値は、次回も関数を実行するときはSome(結果となる配列の要素, 次回実行時の引数)
、関数の実行を終了するときはNone
とします。
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 関数 配列
('T -> bool) -> 'T [] -> 'T []
Array.filterと同様に、配列の各要素で実行した関数の結果がtrue
となるものをすべて取り出します。Array.find
では最初にtrue
となる要素のみとなるのが違います。
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 要素数 配列
int -> 'T [] -> 'T [] []
指定した要素数だけ位置が連続する配列を要素とするジャグ配列を得られます。要素数が正の整数でないときはSystem.ArgumentException
が発生します。また、要素数が配列の要素の数を上回ると結果の配列は空となります。
要素数を2に指定すると結果がArray.pairwise
と似てきますが、要素がタプルか配列かが違います。Array.chunkBySize
との違いは、ただ配列の要素を区切るのではなく、先頭の要素から順次要素数だけ連続する要素を1つの配列にまとめているところです。
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
'T [] -> 'U [] -> ('T * 'U) []
配列1と配列2の各要素のすべての組み合わせをタプルの要素とする配列を得られます。結果となる配列の長さが膨大になる可能性があるため、引数の配列の長さに注意してください。また、引数の配列のどちらかが空のときは結果の配列も空になります。
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) []
ドキュメントが更新されたら、このページは不要になると思いますが、その時までご覧になった方々の参考になればと思います。