Sc283(1) 情報科学応用演習I 資料 (Part 10) 

[解説] 多次元配列

配列の要素に,さらに配列オブジェクトを代入することで, 多次元の配列を作ることができる.(下図参照)

2次元配列

上図の場合,x[i] の各々が値として配列オブジェクトを持つことになるので, i 番目の配列オブジェクトの j 番目の変数は x[i][j] と表現される. これは,(x[i])[j] という意味で,x[i]y に代入 (y = x[i];) すると,y[j] と同じになる.(下図)

2次元配列

通常の (1次元の) 配列では,配列オブジェクトを生成して,変数に代入して用いるが, 2次元の配列の場合,「1次元目」の配列オブジェクトの各々の変数ごとに, 個別の配列オブジェクトを生成して代入する必要がある. したがって,例えば 10x10 の2次元配列の定義 (配列オブジェクトの生成) は,以下のようになる.

var i;
var x = new Array(10);      // x[0] 〜 x[9]
for(i=0; i<10; i++) {
    x[i] = new Array(10);   // x[i][0] 〜 x[i][9]
}

なお,最初に配列オブジェクトをすべて生成しておこうとすれば,上のようになるが, 通常は,プログラムの進行に合わせて,流れの中で生成することも多い.

式の中での配列要素の使用や,配列要素への代入には,x[i][j] のような表現を用いる.


[タスク] 九九表 (2)

概要

先の Part 9 のタスクの 九九表 のプログラムと同様のプログラムを, 2次元配列を用いて作成する.

方法

以下に Part 9 のタスクの例のコードをもとにした雛形を参考に付けておく. (流れ図の例

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<title>JavaScript Sample 10-1</title>
<body>
<script type="text/javascript">
<!--
var n, m;   // for の制御変数,兼,乗数

// ここで配列を用意する.

// 下の for の2重ループは,Part 9 のタスクと同じものを2つ並べてある.
// 1つは九九を計算して配列に格納するように直し,
// もう1つは配列のデータを画面に表示するように直す.

// 九九を計算して配列に格納する.画面への表示は不要.
// document.writeln('<table border>');    // これは不要
for(n=1; n<10; n++){
    // document.write('<tr>');            // これは不要
    for(m=1; m<10; m++){
        // document.write('<td>' + (n*m) + '</td>');
        // ここでは,画面表示のかわりに計算結果を配列に格納する.
    }
    // document.writeln('</tr>');         // これは不要
}
// document.writeln('</table>');          // これは不要

// 配列のデータを画面に表示する
document.writeln('<table border>');
for(n=1; n<10; n++){
    document.write('<tr>');
    for(m=1; m<10; m++){
        // document.write('<td>' + (n*m) + '</td>');
        // ここでは,n*m のかわりに配列のデータを画面に表示する.
    }
    document.writeln('</tr>');
}
document.writeln('</table>');
// -->
</script>
</body>

以下に例を示す.リンクをクリックすれば実行できる.(別ウィンドウで実行される)

js10-1a.html雛形,例のコードと流れ図


[解説] 連想配列

(参考: オブジェクト(Object) in とほほのJavaScriptリファレンス)

一般オブジェクト (Object)

JavaScript の一般オブジェクト (Object) は,内部に名前つきの変数 (プロパティ)を(任意個数)持つことができる構造体で, new 演算子を Object() 関数に作用させて生成する. その際,配列 (Array) オブジェクトと異なり, あらかじめサイズを決める必要はない. 実は,配列オブジェクトも,サイズを指定しないで new Array() のように生成することができる.また,サイズを指定してもしなくても, 範囲外の番号の配列要素に代入すれば,必要な要素は自動的に生成されるため, サイズを後から拡大していくこともできる. (参考: 配列(Array) in とほほのJavaScriptリファレンス)

生成された一般オブジェクトは,通常,変数に代入して用いる. 変数 x に代入した一般オブジェクトの y という名前のプロパティ(変数)は, x["y"] または x.y と表わす. この表現は,式中で用いることもできるし,値を代入することもできる. 前者の表現からも分かるように,この一般オブジェクトは名前で参照する配列と考えることもできる. そのため,この一般オブジェクトは連想配列とも呼ばれる. なお,プロパティは,初めて値が代入されたときに自動的に生成されるので, プロパティの名前をあらかじめ宣言しておく必要はない.

// 一般オブジェクトを生成して変数 x に代入
var x = new Object();  

// x に代入された一般オブジェクトのプロパティに値を代入する
x.firstName = "Kinya";      // x["firstName"] = "Kinya"; としても同じ
x["lastName"] = "MIURA";    // x.lastName = "MIURA"; としても同じ

alert(x.lastName + " " + x.firstName);          // 値の取り出し
alert(x["lastName"] + " " + x["firstName"]);    // 値の取り出し
オブジェクト

オブジェクトリテラル

new 演算子と Object() 関数を用いる方法のほかに, あらかじめ内容が定まっている一般オブジェクトは,名前と値をコロンでつないだ対をコンマで区切って並べ, { } で括って表現することもできる.例えば以下の (A), (B) は等価である.

(A)
var id = new Object();
id.firstName = "Kinya";
id.lastName = "MIURA";
id.phone = "8692";
id.mail = "miura@mail.kobe-c.ac.jp";
(B)
var id = { firstName: "Kinya", lastName: "MIURA",
           phone: "8692", mail: "miura@mail.kobe-c.ac.jp" };

このような({ } で括った)表現をオブジェクトリテラルと呼ぶ.

for-in ステートメント

一般オブジェクトの個々のプロパティすべてに対して何か処理をしたい場合, for-in ステートメントを用いるのが一般的である. for-in ステートメントの基本的な書き方は以下の通りである.

for (変数 in ) 反復パート

この は一般オブジェクトを表す式である. このような for-in ステートメントを実行すると, が表すオブジェクトのプロパティ一つ一つについて,そのプロパティの名前が文字列として 変数 に代入されて 反復パート が実行される.一般オブジェクトの中の全てのプロパティを見るためには, この for-in ステートメントを用いて参照するのが一般的であるが,Firefox の JavaScript では, toSource() というメソッドを用いることもできる. 例えば,変数 id に入っている一般オブジェクトに対して, id.toSource() のように toSource() メソッドを実行すると, オブジェクトリテラルと同様な形式で, オブジェクトの内容を表す文字列が得られる.

var id = { firstName: "Kinya", lastName: "MIURA",
           phone: "8692", mail: "miura@mail.kobe-c.ac.jp" };
var i;

document.write('<pre>');
for (i in id) { // id のプロパティ1つ1つについて反復する
    document.writeln(i + ": " + id[i]);
}
document.write('</pre>');

実行可能な例

(参考: 繰り返し(for) in とほほのJavaScriptリファレンス)

一般オブジェクトと配列オブジェクトの組み合わせ

配列オブジェクトの配列を作ることで多次元配列を作ることができたように, 一般オブジェクトの配列,配列オブジェクトの連想配列 … など, 配列オブジェクトや一般オブジェクトを組み合わせることで,さまざまな形式の複雑なデータ構造を作ることができる.

例えば,一般オブジェクトの配列や連想配列を用いると,定型的なデータを多数扱うような, 一種のデータベースのような構造が構成できる.以下に例を示す.

// 一般オブジェクト(連想配列)の配列
var DB1 = [
  { id: "deguchi", name: "出口 弘",     phone: "8600", room: "JD-313" },
  { id: "miura",   name: "三浦 欽也",   phone: "8692", room: "JD-315" },
  { id: "kuro",    name: "岡田山 クロ", phone: "なし", room: "" }
  // 最後の要素の後は "," は要らない.
];

// 一般オブジェクト(連想配列)の連想配列
var DB2 = {
  deguchi: { id: "deguchi", name: "出口 弘",     phone: "8600", room: "JD-313" },
  miura:   { id: "miura",   name: "三浦 欽也",   phone: "8692", room: "JD-315" },
  kuro:    { id: "kuro",    name: "岡田山 クロ", phone: "なし", room: "" }
  // 最後の要素の後は "," は要らない.
};

alert(DB1[0].room);      // 「JD-313」と表示される.
alert(DB1[1]["name"]);   // 「三浦 欽也」と表示される.

alert(DB2.miura.phone);  // 「8692」と表示される.
alert(DB2["kuro"].name); // 「岡田山 クロ」と表示される.
alert(DB2["kuro"]["id"]);// 「kuro」と表示される.

実行可能な例


[課題] 計算練習プログラム (3)

課題番号: 10-1
課題名: 計算練習プログラム(3)
ファイル名:task10-1.html
締切: 次回の演習日の直前の日曜日,18:00まで

内容

「計算練習プログラム (2)」 のプログラムに手を加え,一度に出題される10問が全て異なる問題となるようにする.

ヒント

報告について

Moodleの課題ページからファイルを提出すること.ファイル名はすべて半角文字とする.