z0.Scala Tips
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>