z0.Scala Tips

print

println

printf

format

s"Hello, $n")

s"${1 + 1}"

f"$n%s $h%2.2f"

f"$n%4s $h%02.2f"

f"$n%-4s $h%-02.2f"

f"$n%-4s $h%+02d"

raw"a\nb"

readf("{0,number}/{1,number}")

readf("{1} {0}")

MessageFormat は次のパターンを使用します。

MessageFormatPattern:

String

MessageFormatPattern FormatElement String

FormatElement:

{ ArgumentIndex }

{ ArgumentIndex , FormatType }

{ ArgumentIndex , FormatType , FormatStyle }

FormatType: one of

number date time choice

FormatStyle:

short

medium

long

full

integer

currency

percent

SubformatPattern

readf:List[Any]

readf1:Any

readf2:Tuple2

readf3:Tuple3

val x:Any = 0

val i:Int = x.asInstanceOf[Int]

readLine

readBoolean

readByte

readShort

readChar

readInt

readLong

readFloat

readDouble

val xs = io.StdIn.readLine().split(' ')

val xs = readLine.split(' ')

xs.mkString(" ")

val xs = readLine.split(' ').map(_.toInt)

for(line <- io.Source.stdin.getLines)

io.Source.stdin.mkString

val scanner = new java.util.Scanner(System.in)

scanner.useDelimiter("/")

while(scanner.hasNext){

println(scanner.next)

}

aaa

object Main extends App{

val a = io.StdIn.readLine.toInt

val sc = new java.util.Scanner(System.in)

val s = sc.next

val s = sc.next()

val b = sc.nextInt

val c = sc.nextDouble

val d1,d2 = sc.nextInt

val ls = List.fill(n)(sc.nextInt)

val as = Array.fill(n)(sc.nextInt)

Array[int].range(0, 10)

Array.tabulate(10)(i => i*i)

val mt = List.fill(m,n)(sc.nextInt)

val xs = List(sc.nextInt, sc.nextInt, sc.nextInt)

val cs = for(_<- 1 to 10) yield sc.nextDouble

タプルのソートもできる

val sxs = xs.sorted(Ordering[Double].reverse) //安定でない

val sxs = xs.sortBy(_.toLowerCase)

val sxs = xs.sortBy(x => (f(x),g(x)))

val sxs = xs.sortWith( (a1,a2) => a2 >= a1)

val sxs = xs.sortWith( _ >= _)

xs.take(2)

xs.map(scala.math.round)

xs.foreach(println)

for {

i <- xs

if i < 10

if i > 0

}

}

aaa

var map = ks.zip(vs).toMap

val v = map(k)

val v = map.getOrElse(k,0)

map = Map("a" -> 0, "b" -> 1, "c" -> 2)

map.contains(v)

map.keys

map += (k -> v)

map.toSeq.sorted

map.toSeq.sortBy{case (k,v) => (f(k), g(v))}

map.toSeq.sortBy{case (k,v) => k}

map.toSeq.sortBy{kv => kv._1}

map.toSeq.sortBy{_._1}

map.toSeq.sorted

map.toSeq.sortWith((f,g) => f._1 < g._1)

map.toSeq.sortWith(_._1 < _._1)

val zs = xs.sortBy(a => -a)

文字列操作

"*" * 10

"abcdef" take(3) -> "abc"

"abcdef" slice(0,4) -> "abc"

sameElements

"abc".padTo(6, ' ') 文字列に指定長になるまでパッド文字を追加する

head : 先頭

last : 末尾

init : 末尾以外

tail : 先頭以外

xs zipWithIndex

xs zipAll ys x y

xs grouped n

xs sliding n

object Main extends App{

val ls = (0 to 1000).toList.par

println(ls.sum)

println(ls.size)

println(scala.collection.parallel.availableProcessors)

}

synchronized {

scanner.nextInt

}

scala> def add(a:Int,b:Int) = a + b

add: (a: Int, b: Int)Int

scala> add(12,34)

res0: Int = 46

scala> add _

res1: (Int, Int) => Int = <function2>

scala> add

<console>:13: error: missing argument list for method add

Unapplied methods are only converted to functions when a function type is expected.

You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.

add

scala> add(1,_:Int)

res16: Int => Int = <function1>

scala> add(1,_:Int)(2)

<console>:13: error: Int does not take parameters

add(1,_:Int)(2)

^

scala> (add(2,_:Int))(2)

res21: Int = 4

scala> val b = add(2,_:Int)

b: Int => Int = <function1>

scala> b

res18: Int => Int = <function1>

scala> b(2)

res20: Int = 4

scala> val add = (a:Int,b:Int) => a+b

add: (Int, Int) => Int = <function2>

scala> add(12,34)

res0: Int = 46

scala> add

res1: (Int, Int) => Int = <function2>

scala> add.curried

res8: Int => (Int => Int) = <function1>

scala> add.curried(1)

res9: Int => Int = <function1>

scala> add.curried(1)(2)

res10: Int = 3

scala> add _

res12: () => (Int, Int) => Int = <function0>

f:Function1

f.andThen(g:Function1)

f.compose(g:Function1)

f.curried

f.tupled

def numberCheck( n:AnyVal ) = n match {

case b:Boolean => b

case i:Int if i >= 0 => i

case x => x

}

abstract case class A

case class B(n:Int) extends A {

}

case class C(n:Int) extends A{

}

a match {

case B(n) => n

case C(n) => n

case D(n , E(m)) => (n,m)

case List(x,y) =>

case x::xs =>

case Nil =>

case (f1,f2) =>

case _ =>

}

val re0 = "aa\d+".r

val re2 = "aa(\d+)bb(\d+)".r

val re3 = re2.unanchored

a match {

case re0() =>

case re2(n,m) =>

}

val x::xs = List(1,2,3)

val (x,y) = (1,2)

val n = B(1)

for( B(n) <- xs)

for( (k,v) <- xs)

import java.text.DateFormatSymbols

import java.util.Locale

import java.util.Calendar

val cal = Calendar.getInstance()

cal.set(Calendar.YEAR, 2017)

cal.getActualMaximum(Calendar.DAY_OF_YEAR) == 366

a1.sameElements(a2)

import scala.collectoin.mutable.PriorityQueue

val pq = new PriorityQueue[Int]

val pq = new PriorityQueue[Int](Ordering[Int].reverse)

pq.isEmpty

pq.enqeue(1)

pq += 2

pq.deqeue

pq.head

Seq(1, 2, 3)(2)

Seq(1, 2, 3) length

Seq(1, 2, 3, 2) indexOf (2) 見つからない場合 -1

eq(1, 2, 3, 2) lastIndexOf (2)

Seq(1, 2, 3, 2, 3) indexWhere (_ == 2)

4 +: Seq(1, 2, 3)

Seq(1, 2, 3) :+ 4

Seq(1, 2, 3) intersect Seq(2, 3, 4, 5, 6)

Seq(2, 3, 4, 5, 6) diff Seq(1, 2, 3)

Seq(2, 3, 4, 5, 6) union Seq(1, 2, 3)

immutableList

val la = List(1,2)

val lb = List(1,2)

1 :: la

la ::: lb

mutableList

val ls = LinkedList(1,2,3)

val ls = ListBuffer(1,2,3)

val ls = MutableList(1,2,3)

val ls = LinkedList(1,2,3)

ls += 4

0 +=: ls

ls - 1 すべて削除される

ls -- List(1,2) すべて削除される

ls.remove(2) 削除した値が戻り値

val ab = scala.collection.mutable.ArrayBuffer(1, 2, 3, 2)

ab -= 2 最初の1つが削除される 戻り値はコレクション

ab --= List(1,2) 複数の値が削除される

ab remove(1) インデックス指定で削除

ab remove(1,3) インデックス指定で3個削除

ab insert(1)

ab insertAll(1,List(1,2))

ab contains 2 -> true false :Boolean

ab indexOf 2 -> -1 or index:Int

ab count 2

ab find (_ > 0) -> Some(1) None:Option[Int]

val (l,r) = Array(1,2,3,4).splitAt(2) インデックス2以降と分割

val (f, b) = (0 to 9).partition(_ > 4)

Sorting.stableSort(list, (s: String) => (s.length, s))

foreach色々

scala> (0 to 0) foreach(println)

0

scala> (0 to -1) foreach(println)

scala> (0 to 1) foreach(println)

0

1

scala> (0 to 1) foreach(println _ )

0

1

scala> (0 to 1) foreach(_ => println _ )

scala> (0 to 1) foreach(_ => println(_) )

<console>:12: error: missing parameter type for expanded function ((x$2) => println(x$2))

(0 to 1) foreach(_ => println(_) )

^

scala> (0 to 1) foreach(_:Int => println _ )

<console>:1: error: ')' expected but '_' found.

(0 to 1) foreach(_:Int => println _ )

^

scala> (0 to 1) foreach(_:Int => println(_) )

<console>:1: error: ')' expected but '(' found.

(0 to 1) foreach(_:Int => println(_) )

^

<console>:1: error: ';' expected but ')' found.

(0 to 1) foreach(_:Int => println(_) )

^

scala> (0 to 1) foreach(_ => println )

scala> (0 to 1) foreach(i => println i )

<console>:12: error: value i is not a member of Unit

(0 to 1) foreach(i => println i )

^

scala> (0 to 1) foreach(_ => println(i) )

<console>:12: error: not found: value i

(0 to 1) foreach(_ => println(i) )

^

scala> (0 to 1) foreach(i => println(i))

0

1

scala> (0 to 1) foreach println

0

1

scala> (0 to 1) foreach (println _ )

0

1

scala> (0 to 1) foreach({i => println(i)} )

0

1

scala> (0 to 1) foreach {i => println(i)}

0

1

scala> List((0,1),(2,3)) foreach{x => println(x)}

(0,1)

(2,3)

scala> List((0,1),(2,3)) foreach{case k,v => println(k,v)}

<console>:1: error: '=>' expected but ',' found.

List((0,1),(2,3)) foreach{case k,v => println(k,v)}

^

scala> List((0,1),(2,3)) foreach{case (k,v) => println(k,v)}

(0,1)

(2,3)

scala> (0 to 1) foreach(_ => println)

scala> (0 to 1) foreach(_ => println())

scala> (0 to 1) foreach _ => println()

<console>:1: error: ';' expected but '=>' found.

(0 to 1) foreach _ => println()

^

scala> (0 to 1) foreach(println())

<console>:12: error: type mismatch;

found : Unit

required: Int => ?

(0 to 1) foreach(println())

^

scala> (0 to 1) foreach(println)

0

1

scala> (0 to 1) foreach{println}

0

1

scala> (0 to 1) foreach println

0

1

scala> (0 to 1) foreach println _

0

1

scala>

ls.foreach{ _ match {case x:Int => print('a) ; case _ => print('x)}}

'a'x'a

ls.foreach{ _ match {case x:Int => 'a ; case _ => 'x}}

foreachの返却値は () ユニット

ls.foreach{ x => x match {

引数が1個のときは、()省略できる

ls.foreach( _ match {

ブロックが1つしかないブロックは {} が省略できる

ls.foreach _ match {

両方省略するとエラー。 _ の扱いでか? foreach の関数化で。

scala> ls map _

<console>:13: error: missing parameter type for expanded function ((x$1) => ls.map(x$1))

ls map _

^

scala> ls foreach _

<console>:13: error: missing parameter type for expanded function ((x$1) => ls.foreach(x$1))

ls foreach _

^

ドットを付けたときのエラー ls() の型は Int に対して、 foreach の型は、(Any => Any) => Unit で型に互換がない。

.の結合より、 省略した方が弱い。 ls.apply(foreach)

scala> ls.foreach _ match {case x:Int => print('a) ; case _ => print('x)}

<console>:13: error: pattern type is incompatible with expected type;

found : Int

required: (Any => Any) => Unit

ls.foreach _ match {case x:Int => print('a) ; case _ => print('x)}

^

ドットを省略したときのエラー foreach _ と _ が foreachの引数として結合する。 _ の型指定が無いので、エラー。

scala> ls foreach _ match {case x:Int => print('a) ; case _ => print('x)}

<console>:13: error: missing parameter type for expanded function

The argument types of an anonymous function must be fully known. (SLS 8.5)

Expected type was: ?

ls foreach _ match {case x:Int => print('a) ; case _ => print('x)}

ls foreach x => x match {case x:Int => "a" ; case _ => "x"}

これは文法エラー

ls foreach x ; とforeachの引数1個分で切れるので、 ; が必要

PartialFunction 引数の一部でしか値が定義されていない関数 で引数が1個の場合は、 case だけで書ける。

scala> ls.foreach{case x:Int => print('a) ; case _ => print('x)}

'a'x'a

scala> ls map {case x:Int => "a" ; case _ => "x"}

res20: List[String] = List(a, x, a)

イテレーターは1度しか参照できない。

val it = Iterator(1, 2, 3)

it.size は3

くりかえして

it.size は0

順列・並べ替え

List(1,2,3).permutations.foreach(println)

List(1,2,3).combinations(2).toList

(1 to 10).grouped(3).foreach(println)

(1 to 10).sliding(3).foreach(println)

遅延リスト

0 #:: 1 #:: 2 #:: Stream()

Stream(0,1,2)

Stream(0 to 10) これは、 Stream((0 to 10)) と処理されて、Range要素が1のストリームになる。

Stream.range(0,10)

Stream.range(0,10,2)

Stream.from(0)

Stream.from(0, 2)

Stream.continually(1) 要素は生成されるたびに評価される

Stream.fill(10)(0) 個数を指定して要素を並べる

scala> val a = scala.collection.mutable.ArrayBuffer()

a: scala.collection.mutable.ArrayBuffer[Nothing] = ArrayBuffer()

val a = scala.collection.mutable.ArrayBuffer[Char]()

a + 'A' エラー

a += 'A'

a += "ABC" エラー

a ++ "ABC"

a ++= "ABC"

'A' +: a

"ABC" ++: a

"ABC" ++=: a

for( Some(x) <- seq ; i <- xs if cond ; a=x) yield { blocks; (a,b,c) }

型で抽出とガードと値の定義

for と foreach と while と do while

for と foreach withFilter map flatMap

for だけ -> foreach

for + yield -> map

for 複数ジェネレータ + yield -> flatMap + map

xs filter( cond )

xs withFilter( cond ) map or foreach

xs indexOf( elm )

xs indexWhere( cond )

xs takeWhile( cond )

mp mapValues( v => f(f))

mp keys

mp keySet

mp values

xs map

xs reaversMap

xs distinct

xs intersect ys

xs union ys

xs diff ys

xs count(cond)

xs take(n)

xs drop(n)

xs takeRight(n)

xs dropRight(n)

xs takeWhile(cond)

xs dropWhile(cond)

xs partition(cond)

xs span(cond) -> takeWhile + dropWhile

xs groupBy( e => f(e) )

xs min minBy(cond)

xs max maxBy(cond)

xs foldLeft

xs scanLeft

xs reduce~ は fold~の 初期値として xs の第1要素を使用する。

並列コレクションの振る舞い

scala.collection.parallel.availableProcessors

xs fold(e)( conv )

xs aggregate(e)( conv1 ) ( conv2 )

xs reduce

fold は 結合律を満たす演算が必須 途中のどこかから、左右のどちらから計算をしても結果は同一 → 並列コレクションに対応できる

foldLeft foldRight は結合の方向を指定して実行。シーケンシャルな処理が必須の場合に使う。

aggregate は、xs を分割して並列で conv1 で集約し、分割ごとの集約結果を conv2 で集約する。

conv2 を conv1と異なるものにする意味は?

conv1の分割処理の結果がリストや文字列なら、整列済みや整形済を期待できる。

その場合、conv2ではより効率の良い集約方法を提供できるかから?

fold は conv1 で分割ごとに集約後、 分割ごとの集約結果をconv1 で集約する。 conv1 == conv2

scala> val a:(Int,Char,String) =>Int = _ + _ + _.toInt

a: (Int, Char, String) => Int = <function3>