トラック
/
JavaScript
JavaScript
/
演習
/
ラッキーナンバー
ラッキーナンバー

ラッキーナンバー

学習演習

はじめに

JavaScriptでは、値はさまざまな型を持つことがあります。変数の型を変更するには、明示的に型変換を行います。 それだけでなく、JavaScriptは文脈上必要なときに型強制(暗黙の型変換)も行います。

型変換

JavaScriptには、ほかの多くの言語にあるような(別の)型へキャストする構文はありませんが、代わりにいくつかの組み込みヘルパーを使えます。 とくに、Boolean、Number、Stringは関数として使うことで、値を対応する型に変換できます。

真偽値への変換(truthyとfalsyの値)

Boolean(value)を使うと、どんな値でも真偽値に変換できます。 falseに変換される値は、falsyと呼ばれる決まったものだけです。 とくに、false、0、空の文字列、null、undefined、NaNがfalsyです。

それ以外の値に対しては、Booleanはtrueを返します。 これらの値をtruthyと呼びます。

Boolean(-1);
// => true

Boolean(0);
// => false

Boolean(' ');
// => true

Boolean('');
// => false

前述のルールにより、JavaScriptでは'0'、'false'、[]、{}がtruthyであることに注意してください。

数値への変換

Number(value)を使うと、値を数値に変換できます。 文字列の先頭と末尾にある空白は無視され、空の文字列は0に変換されます。 プリミティブではない値や、数値を表していない文字列を変換しようとすると、結果はNaN(数値ではない)になります。

Number('  -12.34  ');
// => -12.34

Number('1,2');
// => NaN

Number('');
// => 0

Number({ num: 123 });
// => NaN

文字列への変換

String(value)を使うと、値を文字列に変換できます。 プリミティブな値では、結果は予想どおりのものになります。

String(12.34);
// => '12.34'

String(false);
// => 'false'

String(null);
// => 'null'

String(undefined);
// => 'undefined'

配列の場合、String関数は各要素に文字列への変換を適用し、その結果をカンマで連結します。 joinメソッドを自分で使って、区切り文字をカスタマイズすることもできます。 この場合、nullとundefinedは空の文字列に変換されることに注意してください。

String([42, null, true, 'abc']);
// => '42,,true,abc'

オブジェクトの場合、Stringはデフォルトで役に立たない文字列を返します。

String({ key: 'value' });
// => '[object Object]'

型強制

特定の文脈では、JavaScriptはある文を評価する前に、値を自動的に別のデータ型に変換します。 この暗黙の変換を型強制と呼びます。

真偽値の文脈

真偽値ではない値が真偽値の文脈で使われると、JavaScriptはBoolean関数と同じルールで、その値を暗黙に変換します。

真偽値への型強制は、主に次のような場面で起こります。

  • if文の条件
  • 三項演算子?の最初のオペランド
  • 論理NOT演算子!のオペランド
  • 論理AND演算子&&と論理OR演算子||のオペランド(式の結果はオペランドの一方であり、必ずしも真偽値ではありません)
const num = 0;
if (num) {
  // this block is NOT executed because 0 is falsy
}

文字列の文脈

プリミティブな値に対して加算演算子+が使われ、一方のオペランドが文字列のときは、もう一方も文字列に型強制されます。 変換のロジックはString関数を使ったときと同じです。 その後、2つの文字列が連結されます。

let name;
'hello ' + name;
// => 'hello undefined'

数値の文脈

多くの演算子は、前述のNumber関数のロジックに従って、必要に応じてオペランドを数値に型強制します。

  • 算術演算子:+(文字列が関与しない場合)、-、*、/、%、**
  • 単項プラス演算子と単項マイナス演算子:+、-
  • 関係演算子(文字列以外のオペランドの場合):>、>=、<、<=
  • ビット演算子:|、&、^、~

これらの演算子の詳細については、MDNの演算子一覧を参照してください。

間違いを避けるためには、これらの演算子を適用する前に、常にNumberを明示的に呼び出すのがよい習慣です。

説明

友人のKojoは数字が大好きです。 彼は「fun-with-numbers」という小さなウェブサイトを運営しています。 Kojoはプログラミングがそれほど得意ではないので、助けを求めてきました。

これから、Kojoのウェブサイトで新しい数字ゲームを作るための2つのヘルパー関数と、ユーザーが入力する値を検証する3つ目の関数を作ります。

1. スロットマシンの数字の合計を計算する

Kojoのウェブサイトのゲームのひとつは、数字が書かれたリールが2組表示されるスロットマシンのようなものです。 それぞれの数字の組が1つの数値を表しています。 ゲームの仕組みのために、Kojoはこれら2つの数値の合計を知る必要があります。

2つの配列を入力として受け取るtwoSum関数を書いてください。 それぞれの配列は、0から9までの数値が1つ以上入っています。 この関数はそれぞれの配列を1つの数値として解釈し、2つの数値の合計を返します。

twoSum([1, 2, 3], [0, 7]);
//=> 130

// [1, 2, 3] represents 123 and [0, 7] represents 7.
// 123 + 7 = 130

2. 数値が回文かどうかを判定する

ウェブサイトのもうひとつのゲームは、「ラッキーナンバー」という小さなクイズです。 ユーザーが数値を入力すると、その数値が何か秘密の数列やパターンに当てはまるかどうかがわかります。 「ラッキーナンバー」の数列やパターンは毎月変わり、それぞれのユーザーがそれを推測できる回数は限られています。

今月のラッキーナンバーは、回文になる数値です。 回文数は、数字を逆に並べても同じ数値になります。

数値を入力として受け取る新しいluckyNumber関数を実装してください。 この関数は、その数値が回文であればtrueを、そうでなければfalseを返します。 入力される数値は常に正の整数です。

luckyNumber(1441);
//=>  true

luckyNumber(123);
//=> false

3. 不正なユーザー入力に対するエラーメッセージを生成する

ウェブサイトのさまざまな場所に、ユーザーが数値を入力してボタンをクリックすると何かの操作が実行される入力欄があります。 Kojoは自分のサイトのユーザー体験を改善したいと考えています。 ユーザーがボタンをクリックしたものの、入力欄に不正な値が入っている場合に、エラーメッセージを表示したいのです。

入力欄の値がどのように渡されるかについて、もう少し詳しく説明します。

  • ユーザーが入力欄に何かを入力すると、たとえ数字だけを入力しても、対応する値は常に文字列になります。
  • ユーザーが何かを入力したあとでそれを削除すると、その変数は空の文字列になります。
  • ユーザーがまだ入力を始めていない段階では、その変数はundefinedやnullであることもあります。

ユーザーの入力を受け取るerrorMessage関数を書いてください。 ユーザーが何も入力していない場合、errorMessageは'Required field'を返します。 入力が0以外の数値を表していない場合(JavaScriptの変換規則に従った場合)、'Must be a number besides 0'を返します。 それ以外の場合は、入力が正しいとみなしてよく、戻り値は空の文字列です。

errorMessage('123');
// => ''

errorMessage('');
// => 'Required field'

errorMessage('abc');
// => 'Must be a number besides 0'
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
JavaScript Exercism

ラッキーナンバーを始める準備はできましたか?

Exercismに登録すれば、37個のコンセプト159個の演習、そして本物の人間によるメンタリングとともに、JavaScriptを学んでマスターできます。すべて無料です。