ActionScript 3.0で始めるオブジェクト指向スクリプティング

第8回Stringクラスによる文字列の操作と値を返す関数

前回の第7回は、Dateクラスを使って日付を調べ、アナログ時計のTextFieldに表示させた。今回は、Stringクラスにより文字列を操作して、日付のフォーマットに手を加え、その処理を関数としてまとめてみたい。

Stringクラスを使った文字列の一部取出し

第7回のアナログ時計に表示した日付は、年月日の数字にスラッシュ(/)を挟んで、単純に連結したものだった図1⁠。これを数字2桁に揃えた「YY/MM/DD」というフォーマットにしてみよう。まずは、年の値だ。

図1 年月日にスラッシュ(/)を挟んで単純に連結
図1 年月日にスラッシュ(/)を挟んで単純に連結

文字列の操作には、Stringクラスが利用できる。Stringクラスも、Dateクラスと同じように、インスタンスをターゲットにして、プロパティやメソッドを操作する。しかし、new演算子でインスタンスを作成しなくても、ダブルクォーテーション(")で括って記述した文字列は、そのままStringクラスのインスタンスとして扱える[1]⁠。

たとえば、文字列の文字数はString.lengthプロパティで調べることができる[2]⁠。つぎのスクリプトは、文字列の数字"2007"を変数year_strに格納し、その文字数4を[出力]パネルに表示する。

var year_str:String = "2007";
trace(year_str.length);   // 出力: 4

文字列から文字の一部を取出すには、String.substring()メソッドを用いる。引数は文字位置を指定するインデックス番号で、開始位置と終了位置のふたつだ。なお、インデックス番号は、0から始まる。たとえば、文字列の数字"2007"から末尾の2桁"07"を取出すには、つぎのようにString.substring()メソッドの第1引数に2、第2引数に4を指定する。

var year_str:String = "2007";
trace(year_str.substring(2, 4));   // 出力: 07

文字列のインデックス番号は0から始めるので、第1引数の2は(3文字目なので)よいとして、第2引数の4がわかりにくいかと思う。これはヘルプを見ると、第2引数は「抽出するサブストリングの最後の文字のインデックスに1を加えた整数」とされているからである。

文字そのものを数えるより、文字の間に仕切を想い浮かべると理解しやすいだろう図2⁠。そして、取出したい文字列が、どの仕切からどの仕切の間にあるのかを数えればよい。文字列"2007"の末尾の2桁"07"は、仕切番号2から4の間の文字ということになる。

図2 文字の間に仕切を想い浮かべる
図2 文字の間に仕切を想い浮かべる

すると、ターゲットとなる文字列の、ある文字から最後の文字まで取出したいとき、第2引数はString.lengthプロパティの値と一致することがわかる。したがって、上記スクリプトでString.substring()メソッドメソッドの第2引数を書替えて、year_str.substring(2, year_str.length)と記述しても同じ結果が得られる。

さらにヘルプを確認すると、第2「パラメータを省略すると、String.lengthが使用され」るとある。つまり、文字列の末尾2桁を取得したい場合には、第2引数は省略できる。前回作成したスクリプト2に修正を加えて[3]⁠、年を2桁で表示するようにしてみようスクリプト1⁠。

スクリプト1 年の下2桁を取出して日付表示する
function xSetTime(eventObject:Event):void {
  // [1]Dateインスタンスから時刻と日付のプロパティ値を取得する
  var my_date:Date = new Date();
  var nSeconds:Number = my_date.seconds;
  var nMinutes:Number = my_date.minutes;
  var nHours:Number = my_date.hours;
  var nYear:Number = my_date.fullYear;
  var nMonth:Number = my_date.month+1;
  var nDate:Number = my_date.date;
  // [2]時計の針のアニメーション
  second_mc.rotation = nSeconds*6;
  minute_mc.rotation = nMinutes*6;
  hour_mc.rotation = nHours*30+nMinutes/2;
  // [3]日付のフォーマットを設定
  var year_str:String = String(nYear).substring(2); // 第2引数を省略
  // [4]日付をTextFieldインスタンスに設定
  my_txt.text = year_str+"/"+String(nMonth)+"/"+String(nDate);
}
addEventListener(Event.ENTER_FRAME, xSetTime);

[ムービープレビュー]を確かめると、日付の年は下2桁が表示される図3⁠。

図3 年は下2桁が表示された
図3 年は下2桁が表示された

数字の桁数を揃える

つぎは、月日のフォーマットだ。1桁のときには頭に0を置き、つねに2桁の表示にしたい。このような場合、数字の桁数を調べ、1桁かどうかを条件判定して、1桁の数字には"0"を連結するという処理方法も考えられる。しかし、今回は文字列から一部を取出すメソッドで、条件判定をすることなく処理してみよう。

たとえば、数値1を2桁の文字列"01"に変換するには、つぎのような操作を行えばよい。

var nDate:Number = 1;
var date_str:String = String(nDate+100).substring(1);
trace(date_str);   // 出力: 01

まず、数値の段階で下2桁が00の数値、たとえば100を加算する。すると、数値は101になる。したがって、この3桁の数値を文字列に変換したうえで、下2桁を取出せばよい。

この手法の利点は、加算する数値(100)の下2桁は00なので、もとの日付の数値が2桁(たとえば10)であったとしても、下2桁の数値には影響がないことだ(110でも下2桁は変わらない⁠⁠。つまり、2桁の日付であっても、この操作手順で、もとのままの2桁の数字の文字列が得られる。そのため、もとの数値が1桁か2桁かを判別する必要はない。

前記スクリプト1の月日の値について、この数字を2桁に変換する処理を加えたのが以下のスクリプト2だ。

スクリプト2 月日の数字を2桁に揃える
function xSetTime(eventObject:Event):void {
  // [1]Dateインスタンスから時刻と日付のプロパティ値を取得する
  var my_date:Date = new Date();
  var nSeconds:Number = my_date.seconds;
  var nMinutes:Number = my_date.minutes;
  var nHours:Number = my_date.hours;
  var nYear:Number = my_date.fullYear;
  var nMonth:Number = my_date.month+1;
  var nDate:Number = my_date.date;
  // [2]時計の針のアニメーション
  second_mc.rotation = nSeconds*6;
  minute_mc.rotation = nMinutes*6;
  hour_mc.rotation = nHours*30+nMinutes/2;
  // [3]日付のフォーマットを設定
  var year_str:String = String(nYear).substring(2);
  var month_str:String = String(nMonth+100).substring(1);
  var date_str:String = String(nDate+100).substring(1);
  // [4]日付をTextFieldインスタンスに設定
  my_txt.text = year_str+"/"+month_str+"/"+date_str;
}
addEventListener(Event.ENTER_FRAME, xSetTime);

[ムービープレビュー]を確認すると、年月日がすべて2桁の表示になる図4⁠。

図4 年月日がすべて2桁で表示される
図4 年月日がすべて2桁で表示される

値を返す関数の定義

前記スクリプト2で、月と日を2桁の数字にする処理はまったく同じだ。また、年の下2桁を取出す操作も、工夫すれば同じ処理内容にまとめられそうである。そこで、2桁より大きな数値は下2桁を取出し、2桁以下の数値は2桁の文字列に変換する関数を定義してみよう。

関数の定義に早く慣れるコツは、呼出し方をまず考えることだ。定義する前に、どのように使いたいのかを先に決めてしまうのである。今回定義する関数は、名前をxSetDigits()とし、前記スクリプト2の [3]の「日付のフォーマットを設定」のパートでつぎのように利用したい。

var year_str:String = xSetDigits(nYear);
var month_str:String = xSetDigits(nMonth);
var date_str:String = xSetDigits(nDate); 

ひとつの問題は、もとの数値に1桁から4桁まで幅があることだ。任意の桁数の(数字の)文字列から、下2桁を取出さなければならない。つまり、String.substring()メソッドの第1引数を、どのように計算するかである。String.lengthプロパティで総文字数が調べられるから、つぎのように指定すればよいだろう。

var fullYear_str:String = "2007";
var year_str:String = String(fullYear_str).substring(fullYear_str.length-2);
trace(year_str);   // 出力: 07

これで2桁以上の文字列から、問題なく下2桁を取得することができる。

もうひとつ、今回の関数xSetDigits()は、値を返さなければならない。具体的には、関数xSetDigits()は、年月日いずれかの数値を引数として渡され、それを2桁の文字列に変換して、その値を呼出し元に知らせる必要がある。これが値を返すといわれる処理で、返される値を「戻り値」と呼ぶ。

値を返すには、returnステートメントの後に戻り値を指定する(※4⁠。また、戻り値のデータ型指定は、function定義の括弧()の後に記述する。

function 関数名(引数:データ型):戻り値のデータ型 {
  // 処理内容
  return 戻り値;
}

ここまでの準備が整えば、前記スクリプト2に関数xSetDigits()を定義して、数値を2桁の文字列に変換することができるスクリプト3⁠。

スクリプト3 数値を2桁の文字列に変換する関数xSetDigits()の追加
function xSetTime(eventObject:Event):void {
  // [1]Dateインスタンスから時刻と日付のプロパティ値を取得する
  var my_date:Date = new Date();
  var nSeconds:Number = my_date.seconds;
  var nMinutes:Number = my_date.minutes;
  var nHours:Number = my_date.hours;
  var nYear:Number = my_date.fullYear;
  var nMonth:Number = my_date.month+1;
  var nDate:Number = my_date.date;
  // [2]時計の針のアニメーション
  second_mc.rotation = nSeconds*6;
  minute_mc.rotation = nMinutes*6;
  hour_mc.rotation = nHours*30+nMinutes/2;
  // [3]日付のフォーマットを設定
  var year_str:String = xSetDigits(nYear);
  var month_str:String = xSetDigits(nMonth);
  var date_str:String = xSetDigits(nDate);
  // [4]日付をTextFieldインスタンスに設定
  my_txt.text = year_str+"/"+month_str+"/"+date_str;
}
// [5]数値を2桁の文字列に変換する関数定義
function xSetDigits(n:int):String {
  var temp_str:String = String(n+100);
  var n_str:String = temp_str.substring(temp_str.length-2);
  return n_str;
}
addEventListener(Event.ENTER_FRAME, xSetTime);

動作自体は、スクリプト2と変わらない。年月日がすべて2桁で表示されれば完成である。

次回から、新しい題材に移る。MovieClipインスタンスの座標の扱いについて学習する予定だ。

今回解説した次のサンプルファイルがダウンロードできます。

おすすめ記事

記事・ニュース一覧