ぶろぐ

日記です

関数リテラル

//どちらも結果は同じですな
//jsと同じで、無名関数を生成して変数に突っ込むか、普通に関数を生成するか、の違いみたい

//scala初心者には関数リテラルの方はパッと頭に入ってこない。しかし記号がたくさんあって関数型っぽいかっこよさを感じる
//…と思ったけど、多分関数リテラルのパターン(構文)を覚えれば問題ないな
//(引数名: 型) => {処理}: 戻り値の型

scala> val isEven = (x: Int) => x % 2 == 0
isEven: Int => Boolean = <function1>

scala> def isEvenDef(x: Int) = { x % 2 == 0 }
isEvenDef: (x: Int)Boolean

scala> isEven(2)
res16: Boolean = true

scala> isEven(1)
res17: Boolean = false

scala> isEvenDef(2)
res19: Boolean = true

scala> isEvenDef(1)
res18: Boolean = false


// { } あったほうがわかりやすいなー
scala> val isEven = (x: Int) => {x % 2 == 0}
isEven: Int => Boolean = <function1>

すから

scalaってフレームワークとかORMとかどれ使っていいか悩むな…
playが王道かなー
skinnyはreverse-scaffoldやばいと思って使ってみたけど上手く動かないことがしばしばあるんだよなー(エラー見てもわからん。
複雑なことをやるつもりはないので、なるべく楽できて嵌らないフレームワークを選びたい。
・・・scalaよりgroovyのほうが明らかに簡単な気がする!

たぷる

scala> var hoge = (1,2,3,4)
hoge: (Int, Int, Int, Int) = (1,2,3,4)
//上記、リストが作られると思ったけど、タプルと呼ぶみたい

scala> var hoge = (1, "hoge")
hoge: (Int, String) = (1,hoge)

scala> var hoge: Tuple2[Int, String] = (1, "hoge")
hoge: (Int, String) = (1,hoge)

//リストは以下で。一応型混ぜても大丈夫っぽい。
scala> var hoge = List(1,"hoge",2,"foo")
hoge: List[Any] = List(1, hoge, 2, foo)

scala> var hoge = List(1,2,3,4)
hoge: List[Int] = List(1, 2, 3, 4)

タプル=構造体みたいなイメージで良さそう。固定長Arrayに型をつけました的な。

existsとforall

scala >

//hogeが含まれているか
scala> List("hoge", "hoge").exists(s => s == "hoge")
res90: Boolean = true

//全部hogeかどうか
scala> List("hoge", "hoge").forall(s => s == "hoge")
res91: Boolean = true

//hogeが含まれているか
scala> List("hoge", "foo").exists(s => s == "hoge")
res92: Boolean = true

//全部hogeかどうか
scala> List("hoge", "foo").forall(s => s == "hoge")
res93: Boolean = false

ふん!

import scala.io.Source

// 桁数取得
def widthOfLength(s: String) = s.length.toString.length

if (args.length > 0) {
    // ファイル読み込み
    val lines = Source.fromFile(args(0)).getLines().toList

    // 配列の先頭2つを取り出して処理。その結果と次の要素で処理繰り返す。
    // ex.
    // 1: List(aa,b,ccc,d)
    // 2: aa  b   -> aa
    // 3: aa  ccc -> ccc
    // 4: ccc d   -> ccc
    // 結果は ccc 的な感じ。
    val longestLine = lines.reduceLeft(
        (a, b) => if (a.length > b.length) a else b
    )
    // 最も長い文字数の桁数
    val maxWidth = widthOfLength(longestLine)

    // 表示!!
    lines.foreach(line => {
        // 最大桁数 - 今表示する桁数
        val numSpaces = maxWidth - widthOfLength(line)
        val padding = " " * numSpaces

        // スペース + 文字数 | 文字
        println(padding + line.length + " | "+ line)
    })
}
else
    Console.err.println("Please enter filename")

結果

% scala readfile2.scala readfile.scala
22 | import scala.io.Source
 0 |
22 | if (args.length > 0) {
50 | 	for (line <- Source.fromFile(args(0)).getLines())
33 | 		println(line.length +" "+ line)
 1 | }
 5 | else
45 | 	Console.err.println("Please enter filename")

scalaぱいせん

scala> var str = "String"
str: String = String

scala> str.exists(_.isUpper)
res18: Boolean = true


/****** Map関連 ******/


// 連想配列作る
scala> var ca = Map("us" -> "Washington", "france" -> "paris")
ca: scala.collection.immutable.Map[String,String] = Map(us -> Washington, france -> paris)

// 追加
scala> ca += ("japan" -> "tokyo")

// 中身確認
scala> ca
res55: scala.collection.immutable.Map[String,String] = Map(us -> Washington, france -> paris, japan -> tokyo)

// Mapをforeach
scala> ca.foreach(println)
(us,Washington)
(france,paris)
(japan,tokyo)

// 省略しない標準型
scala> ca.foreach((arg: (String,String)) => println(arg))
(us,Washingthon)
(france,paris)
(japan,tokyo)

// javaやphp風にforeachしたい場合
scala> for(c <- ca) { println(c) }
(us,Washingthon)
(france,paris)
(japan,tokyo)


/****** 変数/関数定義 ******/


// 変数定義
scala> var hoge1 = "hoge1"
hoge1: String = hoge1

scala> var hoge2: String = "hoge2"
hoge2: String = hoge2

// valは定数、varは変数、defはコード

// 関数定義
scala> def max(x: Int, y: Int): Int = {
     | if (x > y) x
     | else y
     | }
max: (x: Int, y: Int)Int

// よんでみる
scala> max(4,3)
res75: Int = 4

scala> max(3,4)
res76: Int = 4


/****** リスト操作 ******/


scala> (1::2::3::Nil).exists(i => i==1)
res70: Boolean = true

scala> (1::2::3::Nil).exists(i => i==4)
res71: Boolean = false

scala> (1::2::3::Nil).filter(i => i==2)
res72: List[Int] = List(2)

scala> (1::2::3::Nil).map(i => i*2)
res73: List[Int] = List(2, 4, 6)