LoginSignup
0
0

More than 3 years have passed since last update.

Scalaでリストを使った簡単な占いを実装してみる

Last updated at Posted at 2020-05-01

きっかけ

大学でプログラムならまずこれを勉強しろと言われ、文字通り1+1しか書けず挫折したScalaを改めて触ってみたいと思う。
少しばかりpythonで簡単な処理は書けるようになったので、今なら理解できるかどうか試してみたくなったのが動機。
ちなみに、Javaは全く触ったことがありません。

コップ本を片手に頑張ります!
理解がおかしかったらご指摘ください。

占い

Randomライブラリを使う。

import scala.util.Random

def fortune(): String = {
  val fortuneNumber: Int = Random.nextInt(3)
  if ( fortuneNumber == 0 ) "大吉"
  else if ( fortuneNumber == 1 ) "吉"
  else "凶"
}

println(fortune())

Randomモジュールを使うことで乱数を扱うことができる。
nextIntメソッドは0から"引数で指定した値 -1"の整数をランダムに出力する。
今回は3パターン出してみたので、nextInt(3)で0, 1, 2が生成される。

あとは、0=大吉、1=吉、2=凶に振り分けて条件分岐。
scalaはelif使えないんですね。

もう少し簡潔に書く

このままだと、出力候補が増えれば増えるほどelse if文が増えるのでイケてない。
じゃんけんみたいな処理だと、数値->文字列の置き換え処理が必要で、非常にイケてないプログラムになることが想像できる。
Randomライブラリにsuffleメソッドがあった。これで返したい値をリスト化し、さらに要素をシャッフルすることが可能。

import scala.util.Random

val fortune = List("大吉", "吉", "凶")
val result = Random.shuffle(fortune).apply(0)

println(result)

ちなみに、shuffle関数を今回用に自分で作るとこんな感じ。

import scala.util.Random

def shuffle(list: List[String]): String = {
  list(Random.nextInt(list.length + 1))
}

val fortune  = List("大吉", "吉", "凶")
val result = shuffle(fortune)

println(result)

頭の整理:配列とリスト

配列とリスト

Pythonだとメソッドを呼び出すときは次のように[]を使った。
配列のデータに直接触りに行って参照しているイメージ。

>>> test = ["one", "two", "three"]
>>> test[0]
'one'
>>>

Scalaはapplyという関数で呼び出しているらしい。
関数なので、指定すべき要素は引数扱いになる。だから()で呼び出す。

scala> test(0)
val res1: String = one

scala> test.apply(0) //同じこと
val res2: String = one

配列とリストの違い

  • 配列:要素は全て同じ型
  • リスト:要素の型はそれぞれ違っていて良い

架空の勇者の情報として、「名前、レベル、魔王討伐状況」を配列、リストにそれぞれ入れることを試す。
※辞書で書けばいい話だけど、今回は練習として。

scala> val testArray = new Array[String](3) //これは配列。そもそもこう書かないと通らない。
val testArray: Array[String] = Array(null, null, null)

scala> testArray(0) = "勇者"

scala> testArray(1) = 20
                      ^
       error: type mismatch; //当然型エラー
        found   : Int(20)
        required: String

scala> testArray(2) = false
                      ^
       error: type mismatch; //当然型エラー
        found   : Boolean(false)
        required: String

scala> val testList = ("勇者", 20, false) //これはリスト
val testList: (String, Int, Boolean) = (勇者,20,false)

リストの定義

先ほどのListの定義を下記のように書くと、エラーが出る。

scala> val test = new List("test")
                  ^
       error: class List is abstract; cannot be instantiated              ^

scala> val test = new List("test": String)
                  ^
       error: class List is abstract; cannot be instantiated

コップ本にはこう書いてある。

List.apply()はscala.Listコンパニオンファクトリーメソッドとして定義されているので、new Listと書く必要はない。

"ファクトリーメソッド"とあるから、
List.apply()の処理で作られるモノが具体的なオブジェクトだから、作り方なListクラスはインスタンスにはできないということ?
飲み込むのに時間がかかりそうなので、これは次の機会に。

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