0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

List関数の確認

Last updated at Posted at 2019-12-27

前にポーカー書いてた時に一個一個試してたList関数の確認履歴。
公式Docに乗ってる範囲しかサポートできてないけど。
https://msdn.microsoft.com/visualfsharpdocs/conceptual/collections.list-module-%5bfsharp%5d

listMethodFestival.fs
type Card = 
  {
    Number : int
    Suit : string
    Write : string
  }

let makeSuitCards suit = 
  [ for i in 1..13 -> 
    {
        Number = i;
        Suit = suit;
        Write = 
          match i with 
            | 1  -> "A"
            | 11 -> "J"
            | 12 -> "Q"
            | 13 -> "K"
            | _ -> i.ToString()
    }]

let makeDeck = makeSuitCards "H" @ makeSuitCards "C" @ makeSuitCards "S" @ makeSuitCards "D"
let cards = makeDeck
let cardsA = makeSuitCards "H"
let cardsB = makeSuitCards "C"
let cardsC = makeSuitCards "S"

// 合体
makeSuitCards "H"
|> List.append (makeSuitCards "C")
|> List.append (makeSuitCards "S")
|> List.append (makeSuitCards "D")
|> printfn "%A"

// 平均を求める floatじゃないとあかんっぽい
[6;5;6;3;5;9] |> List.map(fun elm -> float elm) |> List.average |> printfn "%A"

// 平均を求める 使用項目を指定できる
cards |> List.averageBy(fun elm -> float elm.Number) |> printfn "%A"

// 指定条件に一致するものを抽出
cards |> List.choose(fun elm -> if elm.Number > 10 then Some(elm) else None) |> printfn "%A"

// 指定個数で分割
cards |> List.chunkBySize 4 |> printfn "%A"

// 関数適用してできたListをくっつけて返す(元のやつは含まれない)
cards |> List.collect(fun elm -> [for x in ["H";"C";"S"] -> {Number = elm.Number; Suit = x; Write = elm.Write}]) |> printfn "%A"

// リスト間の比較、違いがあるところまで調べて計算結果を返却、後続は見ない
[1;3;8] |> List.compareWith(fun elm1 elm2 -> elm1 - elm2) [1;3;1]  |> printfn "%A"
// -7

// リストの結合(感覚としてはjoinが近い)
List.concat [makeSuitCards "H"; makeSuitCards "C"; makeSuitCards "S"; makeSuitCards "D"] |> printfn "%A"

// 要素があるかどうか調べる
cards |> List.contains {Number = 1; Suit = "D"; Write = "A"} |> printfn "%A"

// キーを指定して要素数を調べる
cards |> List.countBy(fun elm -> elm.Number) |> printfn "%A"

// 完全に一致するものを省く
cards |> List.distinct |> printfn "%A"
cards |> List.map(fun elm -> elm.Number) |> List.distinct |> printfn "%A"

// 空のリストを作る 初期化用?
List.empty |> printfn "%A"

// 要素のプロパティを指定してあるかどうか調べる
cards |> List.exists(fun elm -> elm.Suit = "S") |> printfn "%A"

// リスト同士で存在チェック、ただし同じ要素数でなければならない
(makeSuitCards "H") |> List.exists2(fun elm1 elm2 -> elm1 = elm2) (makeSuitCards "H") |> printfn "%A"

// Chooseとの使い分けは正直よくわからない
cards |> List.filter(fun elm -> elm.Number > 10) |> printfn "%A"

// containsとは違って要素が返ってくる、なかったらKeyNotFoundException
cards |> List.find(fun elm -> elm = {Number = 1; Suit = "D"; Write = "A"}) |> printfn "%A"

// リストのインデックスが返ってくる(IndexOf)
cards |> List.findIndex(fun elm -> elm = {Number = 1; Suit = "D"; Write = "A"}) |> printfn "%A"

// 前の計算結果を引数としてもらってくる stateは初期値 accは多分stateから型が決められる
cards |> List.fold(fun acc elm -> acc + elm.Number) 0 |> printfn "%A"

// 前の計算結果を引数としてもらってくる 引数2個版
cardsA |> List.fold2(fun acc elm1 elm2 -> acc + elm1.Number + elm2.Number) 0 cardsB |> printfn "%A"

// 前の計算結果を引数としてもらってくる 逆版 |> で流し込めないので微妙に使いにくい?
List.foldBack(fun elm acc -> acc + elm.Number) cards 0 |> printfn "%A"

// 前の計算結果を引数としてもらってくる 後ろから 引数2個版
List.foldBack2(fun elm1 elm2 acc -> acc + elm1.Number + elm2.Number) cardsA cardsB 0 |> printfn "%A"

//中身が全部条件に一致するか調べる
cards |> List.forall(fun elm -> elm.Suit = "S") |> printfn "%b"
cardsA |> List.forall(fun elm -> elm.Suit = "H") |> printfn "%b"

//中身が全部条件に一致するか調べる リスト2個版
List.forall2(fun elm1 elm2 -> elm1.Suit = "H" && elm2.Suit = "C") cardsA cardsB |> printfn "%b"

// 先頭を取り出す lispのcar
cards |> List.head |> printfn "%A"

// リストを初期化
List.init 5 (
     fun elm -> {Number = elm + 1;
         Suit = "S";
         Write = 
           match elm + 1 with 
             | 1  -> "A"
             | 11 -> "J"
             | 12 -> "Q"
             | 13 -> "K"
             | _ -> (elm + 1).ToString()
     }
 ) |> printfn "%A"

// 空か調べる
cards |> List.isEmpty |> printfn "%b"
[] |> List.isEmpty |> printfn "%b"

// foreach
cardsA |> List.iter(fun elm -> printfn "%d" elm.Number)

// foreach 引数2個版
List.iter2(fun elm1 elm2 -> printfn "%d" (elm1.Number + elm2.Number)) cardsA cardsB

// foreach-index
cardsA |> List.iteri(fun i elm -> printfn "%d:%d" i elm.Number)

// foreach-index 引数2個版
List.iteri2(fun i elm1 elm2 -> printfn "%d:%d" i (elm1.Number + elm2.Number)) cardsA cardsB

// 長さ
cards |> List.length |> printfn "%d"

// 関数適用後の新しいリストを作る
cardsA |> List.map(fun elm -> elm.Number * 2) |> printfn "%A"

// 関数適用後の新しいリストを作る 引数2個
List.map2(fun elm1 elm2 -> elm1.Number * elm2.Number) cardsA cardsB |> printfn "%A"

// 関数適用後の新しいリストを作る 引数3個
List.map3(fun elm1 elm2 elm3 -> elm1.Number * elm2.Number * elm3.Number) cardsA cardsB cardsC |> printfn "%A"

// 関数適用後の新しいリストを作る index付き
cardsA |> List.mapi(fun i elm -> i * elm.Number * 2) |> printfn "%A"

// 関数適用後の新しいリストを作る 引数2個 index付き
List.mapi2(fun i elm1 elm2 -> i * elm1.Number * elm2.Number) cardsA cardsB |> printfn "%A"

// 関数適用後の新しいリストを作る 引数3個 index付きの関数はF#-Listの実装見てもないね、map3はあるのになんでやろう

// 最大値を取る
cards |> List.max |> printfn "%A"

// 最大値を取る、条件付き
cards |> List.maxBy(fun elm -> elm.Number = (List.max cards).Number && elm.Suit = "D" ) |> printfn "%A"

// 最小値を取る
cards |> List.min |> printfn "%A"

// 最小値を取る、条件付き -> なんかバグがある気がする。Number=13のものが返ってくる。
// 4.1が原因か?と思って最新コードで試してみたけど結果変わらず。issue投げるべきかもしれぬ。
cards |> List.minBy(fun elm -> elm.Number = (List.min cards).Number && elm.Suit = "C" ) |> printfn "%A"

// インデックス指定でアクセス(.[n]の実装?) -> duplicateになったらしい。ドキュメントには何も書いてないけど
List.nth cards 3 |> printfn "%A"

// nthのかわりにitemを使うとのこと
List.item 3 cards |> printfn "%A"

// 配列からリストに変換
List.ofArray([|1 .. 5|]) |> printfn "%A"

// Seqからリストに変換
List.ofSeq(seq{1 .. 5}) |> printfn "%A"

// trueになったものとfalseになったもの2つのリストに分ける
let partA, partB = cards |> List.partition(fun elm -> elm.Suit = "D" || elm.Suit = "H")
partA |> printfn "%A"
partB |> printfn "%A"

// インデックスを決める関数をぶつけて、並び替える(関数によって、取りうるインデックスの範囲を超えると死ぬ)
cardsA |> List.permute(fun index -> (index + 8) % List.length cardsA) |> printfn "%A"

// 条件に合う最初の要素を取り出す なかったらKeyNotFoundException
cardsA |> List.pick(fun elm -> match elm with | {Number = 1; Suit = "D"; Write = "A"} -> Some elm | _ -> None) |> printfn "%A"


// 前の計算結果を引数としてもらってくる
//(((0+1)+2)+3) = 6
[1;2;3] |> List.reduce(fun acc elm -> acc + elm ) |> printfn "%A"

// 前の計算結果を引数としてもらってくる、後ろから
//(3 - (2 - (0 - 1))) 
//(3 - (2 - (-1))
//(3 - (2 + 1))
//(3 - 3)
//(0)
[1;2;3] |> List.reduceBack(fun elm acc -> acc - elm ) |> printfn "%A"

// 指定値でListを生成する
List.replicate 5 "rep" |> printfn "%A"

// リバース
[1;2;3;4;5] |> List.rev |> printfn "%A"

// foldは最終の結果だけ
// => 115
[1;2;3;4;5] |> List.fold (fun acc elm -> acc + elm) 100 |> printfn "%A"

// scanは履歴がlistで戻ってくる
//  => [100; 101; 103; 106; 110; 115]
[1;2;3;4;5] |> List.scan (fun acc elm -> acc + elm) 100 |> printfn "%A"

// scanを後ろから適用
// => [115; 114; 112; 109; 105; 100]
100 |> List.scanBack(fun acc elm -> acc + elm) [1;2;3;4;5] |> printfn "%A"

// compareを実装してたらいける
[-5;1;-6;7;-2;0] |> List.sort |> printfn "%A"

// 項目に1手間加える、あとはcompare任せ
[-5;1;-6;7;-2;0] |> List.sortBy(fun elm -> abs elm) |> printfn "%A"

// 条件を指定する(ここでは逆順を指定)
[-5;1;-6;7;-2;0] |> List.sortWith(fun elm1 elm2 -> if elm1 < elm2 then 1 else -1) |> printfn "%A"

// 合算(operator + を実装してる必要あり)
[1 .. 10] |> List.sum |> printfn "%d"

// 要素に1手間加えてから合算
[1 .. 10] |> List.sumBy(fun elm -> elm * 2) |> printfn "%d"

// 先頭を除いたリストを返却 Lispのcar
[1 .. 5] |> List.tail |> printfn "%A"

// Arrayに変換
[1 .. 5] |> List.toArray |> printfn "%A"

// Seqに変換
[1 .. 5] |> List.toSeq |> printfn "%A"

// truncate MSDNのリンク切れてて笑う
// 指定数以降の要素を切り捨てるみたい
[1 .. 5] |> List.truncate 3 |> printfn "%A"

// 見つけた要素を返す。なかったらNoneを返す
[1 .. 5] |> List.tryFind(fun elm -> elm = 3)|> printfn "%A"

// 見つかった要素の位置を返す。
[3 .. 59] |> List.tryFindIndex(fun elm -> elm = 59)|> printfn "%A"

// 指定した関数に一致する最初の要素を返す。
let odd elm = elm % 2 = 0
[1 .. 6] |> List.tryPick(fun elm -> if odd elm then Some elm else None )|> printfn "%A"

// ペアのリストを分解する
List.unzip [(1, 2);(3, 4)] |> printfn "%A"

// ペアのリストを分解する 2がないのがちょっときもい。命名するときもめたんじゃないだろうか
List.unzip3 [(1, 2, 3);(3, 4, 5)] |> printfn "%A"

// リストをくっつけてペアにする
List.zip [1;2] [3;4] |> printfn "%A"

// リストをくっつけてペアにする
List.zip3 [1;2] [3;4] [5;6]|> printfn "%A"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?