スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門第31回(命令型プログラミング(3)配列(array) (1))

今回のお題は「命令型プログラミング(3)配列(array) (1)」です。
 
まずは宿題の解答から
type person = {
    id : int
    name : string
    mutable height : float
    }
 
let testSub (lp : person) =
    lp.height <- lp.height + 10.0
    
 
let test () =
    let p1 = { id = 1 ; name = "Ben" ; height = 169.9}
    let p2 = p1
    testSub  p2
    printfn "%A" p1
   
 
test ()
 
(解説)前回とほとんど同じ内容の問題です。
p1はポインタなので、let p2 = p1でp1,p2がヒープ上の同じところをさしていることに注意すれば、結果は次のようになります。
{id = 1;
 name = "Ben";
 height = 179.9;}
 
 さて今日の話題は配列です。
 命令型プログラミングにおける、「値の容器」のNo.1は配列です。(関数型プログラミングではリストです。)配列を定義すると、ヒープ上に、配列用のメモリの塊が確保され、そこへのポインタが与えられます。
 例
> let a = [| 7 ;8 |];;
val a : int array = [|7; 8|]
 
上の例のように、配列を定義するには、要素を;で区切って、両端を[|と|]で、囲みます。
リストと同じで、要素はすべて同じ型でなくてはなりません。
配列の要素の値を調べるのは次のようにします。
 
> let t = a.[0];;
val t : int = 7
 
> let t = a.[1];;
val t : int = 8
 
> let t = a.[2];;
> System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at <StartupCode$FSI_0006>.$FSI_0006.main@()
stopped due to error
 
存在しないインデックスの配列を調べようとするとエラー(例外)がでます。
また、配列はmutableの宣言なしでも、最初からmutableですから、<-によって、値を変化させることができます。
 
> a.[0] <- 9;; 
val it : unit = ()
 
> printfn "%A" a ;;
[|9; 8|]
val it : unit = ()
 
ここで、注意ですが、let a = [| 7;8 |]と定義したとき、aはポインタですから、
let b = aとすると、bはaと同じものを指し示すことになります。
内容が同じだが、メモリ上は別の場所に作られる配列(元の配列のクローン、コピー)を作るには、Array.copy関数を使って次のようにします。
 
> let b = Array.copy a;;
val b : int array = [|7; 8|]
 
こうすれば、aとbは別のメモリ部分を指しているので、つぎのようにbの内容を変更しても、aには影響が及びません。
 
> b.[0] <- 100;;
val it : unit = ()
 
> printfn "a = %A  b = %A" a b;;
a = [|7; 8|]  b = [|100; 8|]
val it : unit = ()
 
初期化用関数もあります。
 

 
>let a :float array = Array.zeroCreate 2;;//型注釈が必要
val a : float array = [|0.0; 0.0|]
 
>let a = Array.create 5 2.0;; //要素数と初期値が引数
val a : float array = [|2.0; 2.0; 2.0; 2.0; 2.0|]
 
> let a = Array.init 6 (fun i -> 2 * i);;//要素数と、indexと値の対応関数が引数
val a : int array = [|0; 2; 4; 6; 8; 10|]
 
配列の生成ではリストと共通の仕組みが使われているので、ほぼリストと同様の手順が使えます。
例、範囲式(range expression)
 
> let a = [| 2 ..10 |];;
val a : int array = [|2; 3; 4; 5; 6; 7; 8; 9; 10|]
 
例、内包表現
 
>let k = [|
            yield 2;
            yield 7;
             |]
val k : int array = [|2; 7|]
 
>let k = [|
            for i in 1 .. 10 do
                yield (i,i+1)
           |]
val k : (int * int) array =
  [|(1, 2); (2, 3); (3, 4); (4, 5); (5, 6); (6, 7); (7, 8); (8, 9); (9, 10);    (10, 11)|]
  
次のようなこともできます。
 
> let k = [|
            for s in ["two";"three";"four"] do
                yield (s + " dishes")
           |];;
 
val k : string array = [|"two dishes"; "three dishes"; "four dishes"|]
 
リストから配列を作ることもできます。
 
> let k = Array.of_list [1;2;3];;
val k : int array = [|1; 2; 3|]
 
逆はつぎのようになります。
 
> let k = List.of_array  [|1;2;3|];;
val k : int list = [1; 2; 3]
 
それでは宿題です。
次のように、配列を定義したとき、それぞれどんな配列ができるでしょうか?
またk1とk2の違いはなんでしょうか。
 
let k1 = [| 
            yield [|5;6|]
            yield [|5;6|]
            yield [|5;6;7|]
           |]
 
let k2 = [|
            let t = [|5;6|]
            for i in 1 .. 2 do
                yield t
            yield [|5;6;7|]
           |]
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

List.of_array

Array.to_list もあるでよ。v-190

No title

書き込みありがとうございます。
それと、遅くなりましたが、「BLUEPIXYさんのブログには、全角空白文字入りのコードを投稿しないことをここに誓います。」
プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。