F# List標準問題精講
この文書は、F#のリストの様々な関数を使いこなすための練習問題集のPart 3 (上級編) である。15問を通して、F#のリスト操作の上級レベルの技術をマスターすることを目指す。
問題36: 2つのリストを結合する (@ 演算子, List.append)
入力:
[1; 2; 3][4; 5; 6]
出力:
[1; 2; 3; 4; 5; 6]
ヒント
@演算子、またはList.append関数を使用する
解答例と解説
let list1 = [1; 2; 3]let list2 = [4; 5; 6]
// @ 演算子を使用let combinedList1 = list1 @ list2
// List.append 関数を使用let combinedList2 = List.append list1 list2
printfn "%A" combinedList1printfn "%A" combinedList2解説:
@ 演算子と List.append 関数はどちらも、2つのリストを結合して新しいリストを作成する。list1 @ list2 と List.append list1 list2 はどちらも [1; 2; 3; 4; 5; 6] を返す。この問題は基礎編の問題3と同じだが、上級編では List.append が @ 演算子の別名であることを理解していることを前提としている。
問題37: リストのリストを1つのリストに結合する
入力:
[[1; 2]; [3; 4; 5]; [6]]
出力:
[1; 2; 3; 4; 5; 6]
ヒント
List.concat関数を使用する
解答例と解説
let listOfLists = [[1; 2]; [3; 4; 5]; [6]]let concatenatedList = List.concat listOfLists
printfn "%A" concatenatedList解説:
List.concat 関数は、リストのリストを受け取り、それらを1つのリストに結合する。この例では、concatenatedList は [1; 2; 3; 4; 5; 6] となる。
問題38: あるリストから別のリストに含まれる要素を除外する
入力:
- リスト1:
[1; 2; 3; 4; 5; 6] - リスト2:
[2; 4; 6]
出力:
[1; 3; 5]
ヒント
List.except関数を使用する
解答例と解説
let list1 = [1; 2; 3; 4; 5; 6]let list2 = [2; 4; 6]let result = List.except list2 list1
printfn "%A" result解説:
List.except 関数は、第1引数のリストから、第2引数のリストに含まれる要素を除外した新しいリストを返す。この例では、list1 から list2 に含まれる要素 2、4、6 が除外され、result は [1; 3; 5] となる。
問題39: リストの先頭の要素を取得する (List.head の例外処理)
入力:
[1; 2; 3]
出力:
1
備考:
List.headは空リストに対して例外を発生させるため、適切に処理すること
ヒント
List.tryHead関数を使用する、またはList.headをtry...with構文で囲む
解答例と解説
let list = [1; 2; 3]
// List.tryHead を使う場合let tryHeadResult = List.tryHead list
match tryHeadResult with| Some head -> printfn "%d" head| None -> printfn "List is empty"
// List.head を try...with で囲む場合try let head = List.head list printfn "%d" headwith | :? System.ArgumentException -> printfn "List is empty"解説:
List.head 関数はリストの先頭の要素を返す。ただし、空リストに適用すると例外が発生する。そのため、安全に扱うには List.tryHead 関数を使用するか、List.head を try...with 構文で囲んで例外をキャッチする必要がある。
List.tryHeadは、リストが空であればNoneを、そうでなければSomeでラップされた先頭要素を返す。try...with構文を使うと、List.headが発生させるSystem.ArgumentExceptionをキャッチして、適切な処理を行うことができる。
この例では、どちらの方法でも 1 が出力される。
問題40: リストの先頭を除いた残りのリストを取得する (List.tail の例外処理)
入力:
[1; 2; 3]
出力:
[2; 3]
備考:
List.tailは空リストに対して例外を発生させるため、適切に処理すること
ヒント
- リストが空かどうかを
List.isEmptyで判定し、条件分岐する
解答例と解説
let list = [1; 2; 3]
if List.isEmpty list then printfn "List is empty"else let tailList = List.tail list printfn "%A" tailList解説:
List.tail 関数はリストの先頭を除いた残りのリストを返す。ただし、空リストに適用すると例外が発生する。そのため、安全に扱うには、事前に List.isEmpty でリストが空かどうかを判定し、条件分岐する必要がある。
この例では、list は空ではないため、List.tail が適用され、[2; 3] が出力される。
問題41: リストの指定されたインデックスの要素を取得する (List.item / List.nth の例外処理)
入力:
[1; 2; 3]- インデックス:
1
出力:
2
備考:
List.item/List.nthはインデックスが範囲外の場合に例外を発生させるため、適切に処理すること
ヒント
List.tryItem関数を使用する、またはList.item/List.nthをtry...with構文で囲む
解答例と解説
let list = [1; 2; 3]let index = 1
// List.tryItem を使う場合let tryItemResult = List.tryItem index list
match tryItemResult with| Some item -> printfn "%d" item| None -> printfn "Index out of range"
// List.nth を try...with で囲む場合 (List.item も同様)try let item = List.nth index list printfn "%d" itemwith | :? System.ArgumentOutOfRangeException -> printfn "Index out of range"解説:
List.item と List.nth 関数はどちらも、リストの指定されたインデックスの要素を返す。ただし、インデックスが範囲外の場合に例外が発生する。そのため、安全に扱うには List.tryItem 関数を使用するか、List.item / List.nth を try...with 構文で囲んで例外をキャッチする必要がある。
List.tryItemは、インデックスが範囲外であればNoneを、そうでなければSomeでラップされた要素を返す。try...with構文を使うと、List.item/List.nthが発生させるSystem.ArgumentOutOfRangeExceptionをキャッチして、適切な処理を行うことができる。
この例では、どちらの方法でも 2 が出力される。
問題42: リストの最後の要素を取得する (List.last の例外処理)
入力:
[1; 2; 3]
出力:
3
備考:
List.lastは空リストに対して例外を発生させるため、適切に処理すること
ヒント
List.tryLast関数を使用する、またはList.lastをtry...with構文で囲む
解答例と解説
let list = [1; 2; 3]
// List.tryLast を使う場合let tryLastResult = List.tryLast list
match tryLastResult with| Some last -> printfn "%d" last| None -> printfn "List is empty"
// List.last を try...with で囲む場合try let last = List.last list printfn "%d" lastwith | :? System.ArgumentException -> printfn "List is empty"解説:
List.last 関数はリストの最後の要素を返す。ただし、空リストに適用すると例外が発生する。そのため、安全に扱うには List.tryLast 関数を使用するか、List.last を try...with 構文で囲んで例外をキャッチする必要がある。
List.tryLastは、リストが空であればNoneを、そうでなければSomeでラップされた最後の要素を返す。try...with構文を使うと、List.lastが発生させるSystem.ArgumentExceptionをキャッチして、適切な処理を行うことができる。
この例では、どちらの方法でも 3 が出力される。
問題43: 配列をリストに変換する
入力:
[|1; 2; 3|]
出力:
[1; 2; 3]
ヒント
List.ofArray関数を使用する
解答例と解説
let array = [|1; 2; 3|]let list = List.ofArray array
printfn "%A" list解説:
List.ofArray 関数は、配列をリストに変換する。この例では、list は [1; 2; 3] となる。
問題44: シーケンスをリストに変換する
入力:
seq { 1; 2; 3 }
出力:
[1; 2; 3]
ヒント
List.ofSeq関数を使用する
解答例と解説
let sequence = seq { 1; 2; 3 }let list = List.ofSeq sequence
printfn "%A" list解説:
List.ofSeq 関数は、シーケンスをリストに変換する。この例では、list は [1; 2; 3] となる。
問題45: リストを配列に変換する
入力:
[1; 2; 3]
出力:
[|1; 2; 3|]
ヒント
List.toArray関数を使用する
解答例と解説
let list = [1; 2; 3]let array = List.toArray list
printfn "%A" array解説:
List.toArray 関数は、リストを配列に変換する。この例では、array は [|1; 2; 3|] となる。
問題46: リストをシーケンスに変換する
入力:
[1; 2; 3]
出力:
seq [1; 2; 3]
ヒント
List.toSeq関数を使用する
解答例と解説
let list = [1; 2; 3]let sequence = List.toSeq list
printfn "%A" sequence解説:
List.toSeq 関数は、リストをシーケンスに変換する。この例では、sequence は seq [1; 2; 3] となる。
問題47: リスト内包表記を使って、1から10までの偶数のリストを作成する
入力:
- なし
出力:
[2; 4; 6; 8; 10]
ヒント
- リスト内包表記を使用する
forループとif条件を組み合わせる
解答例と解説
let evenNumbers = [ for i in 1 .. 10 do if i % 2 = 0 then yield i ]
printfn "%A" evenNumbers解説:
リスト内包表記を使うと、簡潔な記法でリストを生成できる。for ループで i を 1 から 10 まで変化させ、if i % 2 = 0 で i が偶数の場合のみ yield i でリストに要素を追加する。結果として、evenNumbers は [2; 4; 6; 8; 10] となる。
問題48: リスト内包表記を使って、リストの各要素を2乗したリストを作成する
入力:
[1; 2; 3; 4; 5]
出力:
[1; 4; 9; 16; 25]
ヒント
- リスト内包表記を使用する
forループとyieldを組み合わせる
解答例と解説
let list = [1; 2; 3; 4; 5]let squaredList = [ for x in list do yield x * x ]
printfn "%A" squaredList解説:
リスト内包表記の for x in list で list の各要素 x を取り出し、yield x * x で x の2乗をリストに追加する。結果として、squaredList は [1; 4; 9; 16; 25] となる。
問題49: リストの先頭の要素を Option 型で取得する (List.tryHead)
入力:
[1; 2; 3][]
出力:
Some 1None
ヒント
List.tryHead関数を使用する
解答例と解説
let list1 = [1; 2; 3]let list2 = []
let tryHeadResult1 = List.tryHead list1let tryHeadResult2 = List.tryHead list2
printfn "%A" tryHeadResult1printfn "%A" tryHeadResult2解説:
List.tryHead 関数は、リストの先頭の要素を Option 型で返す。リストが空でない場合は Some でラップされた先頭要素を、空の場合は None を返す。
この例では、tryHeadResult1 は Some 1、tryHeadResult2 は None となる。List.head とは異なり、空リストに対して例外を発生させないため、安全に扱うことができる。
問題50: リストの最後の要素を Option 型で取得する (List.tryLast)
入力:
[1; 2; 3][]
出力:
Some 3None
ヒント
List.tryLast関数を使用する
解答例と解説
let list1 = [1; 2; 3]let list2 = []
let tryLastResult1 = List.tryLast list1let tryLastResult2 = List.tryLast list2
printfn "%A" tryLastResult1printfn "%A" tryLastResult2解説:
List.tryLast 関数は、リストの最後の要素を Option 型で返す。リストが空でない場合は Some でラップされた最後の要素を、空の場合は None を返す。この例では、tryLastResult1 は Some 3、tryLastResult2 は None となる。List.last とは異なり、空リストに対して例外を発生させないため、安全に扱うことができる。