Scala 스터디 3
싱글톤 객체
- object로 싱글톤 객체 생성
- 싱글톤 객체는 직접적으로 접근해서 사용할 수도 있고, import 선언으로 이용 가능
- 싱글톤 객체의 메서드는 전역적으로 접근하고 참조할 수 있음
scala> object Bread {
| val name: String = "기본빵"
| def cooking() = println("빵 만드는 중...")
| }
scala> import Bread.cooking // import
scala> cooking
빵 만드는 중...
scala> Bread.cooking
빵 만드는 중...
Companions
- 싱글톤 객체와 클래스가 같은 이름을 사용하면 컴패니언이라고 함
- 컴패니언은 정적 메소드의 보관 장소를 제공하므로, 자바의 satic 정적 데이터는 스칼라에서 컴패니언을 이용하면 됨
- 컴패니언을 이용해 팩토리 메소드 같은 정적 메소드 작성
scala> :paste // companions은 class와 object가 동시에 선언되어야 하므로 paste mode로 입력
class Email(val username: String, val domainName: String)
object Email {
def fromString(emailString:String): Option[Email] = {
emailString.split('@') match {
case Array(a, b) => Some(new Email(a, b))
case _ => None
}
}
}
scala> :paste
var scalaCenterEmail = Email.fromString("[email protected]") scalaCenterEmail match {
case Some(email) => println(
s"""Registered an Email
| Username: ${email.username}
| Domain name: ${email.domainName}
""")
case None => println("Error: could not parse email")
}
scala>
Registered an Email
Username: scala.center
Domain name: epfl.ch
콜렉션 기본 자료 구조
1) Array
- 길이가 고정된 자료구조
scala> val array1 = Array(1, 2, 3)
scala> array1(0) // 배열 데이터 접근 res0: Int = 1
scala> array1(1) = 10 // 배열 데이터 변경
scala> array1(1)
res1: Int = 10
scala> val array2 = Array(3, 4, 5)
scala> val array2 = array1 ++ array2 // 배열 연결하기 ++
scala> val array4 = 0 +: array3 // 배열 앞에 데이터 추가
scala> val array5 = array3 :+ 100 // 배열 뒤에 데이터 추가
2) List
- 가변적인 길이의 데이터를 저장하기 위한 자료구조
scala> val list1 = List(10, 20, 30, 40)
scala> val list2 = (1 to 100).toList
scala> val list3 = array1.toList
scala> list1
List[Int] = List(10, 20, 30, 40)
scala> list1(2)
Int = 30
scala> list1.head
Int = 10
scala> list1.tail
List[Int] = List(20, 30, 40)
3) Set
- 중복을 허용하지 않는 자료구조 전달된 값이 존재하는지 여부를 반환
scala> val s1 = Set(1, 1, 2)
scala> s1
scala.collection.immutable.Set[Int] = Set(1, 2)
// 전달된 값의 존재 여부 반환 scala> s1(1)
Boolean = true
scala> s1(2)
Boolean = true
scala> s1(3)
Boolean = false
4) Tuple
- 불변의 데이터를 저장하는 자료구조
- 여러가지 값을 저장할 수 있음, 패턴매칭에 이용할 수 있음
- 값에 접근할 때는 _1, _2와 같은 형태로 접근
scala> val hostPort = ("localhost", 80) // 튜플
scala> hostPost._1
String = localhost
// 패턴매칭
scala> def matchTest(hostPort: (String, Int)) = hostPort match {
| case ("localhost", port) => println(s"localhost, $port")
| case (host, port) => println(s"$host, $port")
| }
scala> val hostPort1 = ("localhost", 80)
scala> val hostPort2 = ("localhost", 8080)
scala> val hostPort3 = ("127.0.0.1", 8080)
scala> matchTest(hortPort1)
localhost, 80
scala> matchTest(hortPort2)
localhost, 8080
scala> matchTest(hortPort3)
127.0.0.1, 8080
5) Map
- 사전 형식으로 데이터를 저장하는 구조
- 맵의 데이터를 반환하면 Option 타입으로 반환
scala> val map1 = Map(1 -> 2)
scala> val map2 = Map("foo" -> "bar")
// Option 타입으로 반환
scala> map1.get(1) Option[Int] = Some(2)
// getOrElse를 이용하여 키와 일치하는 데이터가 없으면 기본값을 반환하도록 설정
scala> map1.getOrElse(1, 0)
Int = 2
scala> map1.getOrElse(10, 0)
Int = 0
반복문
1) for문
- to는 이하의 리스트 생성, until은 미만의 시퀀스 생성
scala> for (num <- 0 to 3) // 0에서 3이하의 시퀀스 | println(num)
0
1
2
3
scala> for (num <- 0 until 3) // 0에서 3미만의 시퀀스
| println(num)
0
1
2
scala> val strs = Array("A", "B", "C", "D", "E")
scala> for (index <- 0 until str.length) // 배열 길이만큼 인덱스 호출
| println(index, strs(index))
(0,A)
(1,B)
(2,C)
(3,D)
(4,E)
scala> for ((value, index) <- strs.zipWithIndex) // zipWithIndex를 이용해 인덱스 호출
| println(value, index)
(A,0)
(B,1)
(C,2)
(D,3)
(E,4)
scala> val map = Map("k1"->"v1", "k2"->"v2", "k3"->"v3") s
cala> for ((k, v) <- map) // 맵의 키,밸류는 튜플로 전달
| println(k, v)
(k2, v2)
(k1, v1)
(k3, v3)
scala> for (x <- 0 to 2; y <- 0 to 2; if x < 1; if y < 1) // 세미콜론으로 이중 for, 조건식 추가
| println(x, y)
(0, 0)
- for문의 끝에 yield를 이용해 for문에서 생성한 값들의 시퀀스 반환
scala> def fives(n: Int) = {
| for(x <- 0 to n; if x % 5 == 0)
| yield x
| }
scala> for (num <- fives(20))
| println(num)
0
5
10
15
20
// 0 에서 num 미만의 숫자로 이루어진 조합에서 합이 sum인 값의 조합 찾는 함수
scala> def checkSum(num: Int, sum: Int) =
| for(start <- 0 until num; inner <- start until num; if start + inner == sum)
| yield (start, inner); // IndexedSeq 반환
scala> checkSum(20, 32) foreach {
| case (i, j) => println(s"($i, $j)")
| }
(13, 19)
(14, 18)
(15, 17)
(16, 16)
2) while문
- 조건이 true일 동안 반복
scala> var i = 0
scala> do {
| println(i)
| i += 1
| } while(i < 3)
0
1
2
scala> var num = 0
scala> while (num < 3) {
| num += 1
| println(num)
}
0
1
2
콜렉션 함수
1) map
- 각 아이템에 대해 동일한 작업 진행
scala> var list = (1 to 10)
scala> list.map(_+1)
Vector(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
scala> var strs = List("david", "kevin", "james")
scala> strs.map(_.toUpperCase)
List("DAVID", "KEVIN", "JAMES")
2) reduce, fold
- 데이터 집계 시 사용
- 각 함수 모두 L/R 방향 가질 수 있어, 연산별로 방향에 따라 다른 결과 나타냄
- fold() 함수는 기본 값 제공함
scala> var list = (1 to 10)
scala> list.reduce(_+_) // 55
scala> list.reduceLeft(_+_) // 55
scala> list.reduce(_-_) // -53
scala> list.reduceRight(_-_) // -5
scala> list.fold(10)(_+_) // 65
3) groupBy
- key 기준으로 데이터 병합
- 결과를 Map 형식으로 반환하고 전달된 key와 list 형태의 데이터로 반환
scala> var datas = List(("A", 1), ("B", 2), ("C", 6), ("B", 2), ("A", 8), ("C", 2))
// List내 1번째 param의 데이터를 키로 잡고 이를 기준으로 병합
scala> datas.groupBy(_._1).foreach({ case (k, v) => printf("key: %s, value: %s\n", k, v) })
key: A, value: List((A, 1), (A, 8))
key: C, value: List((C, 6), (C, 2))
key: B, value: List((B, 2), (B, 2))
4) filter
// filter: 콜렉션 데이터를 필터링해 없애거나 분류 scala> var list = (1 to 10)
scala> list.filter(_ > 5) // 5 이상의 데이터 분류
Vector(6, 7, 8, 9, 10)
// partition: 콜렉션 분류
scala> list.partition(_%3 == 0) // 2로 나누어 나머지가 0인 데이터 분류
(Vector(3, 6, 9), Vector(1, 2, 4, 5, 7, 8, 10))
// find: 데이터 검색
scala> list.find(_ == 3) // 3 검색
Option[Int] = Some(3)
// takeWhile, dropWhile: 원하는 부분까지 데이터 선택
scala> var list2 = List(1, 2, 3, -1, 4)
scala> list2.takeWhile(_ > 0)
List(1, 2, 3)
scala> list.dropWhile(_ < 3)
List(3, -1, 4)
5) zip
- 두 개의 콜렉션의 같은 인덱스를 묶을 수 있음
- 길이가 일치하지 않으면 작은 개수 만큼만 반환
scala> for (item <- List(1, 2, 3).zip(List(1, 2, 3)))
| println(item)
(1, 1)
(2, 2)
(3, 3)
scala> for (item <- List(1, 2, 3).zip(List(1, 2, 3, 4)))
| println(item)
(1, 1)
(2, 2)
(3, 3)
6) mapValues
- Map 타입의 데이터에서 value만 map 함수 처리하고 싶을 때 사용
scala> var maps = Map("A" -> 1, "B" -> 2, "C" -> 3, "D" -> 4, "E" -> 5)
scala> maps.mapValues(x => x*x).foreach(x => x match { case (k, v) => printf("key: %s, value: %s\n", k, v) }) // value 제곱
key: E, value: 25
key: A, value: 1
key: B, value: 4
key: C, value: 9
key: D, value: 16
scala> var maps = Map("A" -> List(1, 2, 3), "B" -> List(4, 5, 6), "C" -> List(7, 8, 9))
scala> maps.mapValues(_.sum).foreach({ case (k, v) => printf("key: %s, value: %s\n", k, v) }) // value sum
key: A, value: 6
key: B, value: 15
key: C, value: 24
7) sort
// sorted
scala> var list = List(4, 6, 1, 6, 0)
scala> val l_sort = list.sorted
scala> val r_sort = list.sorted(Ordering.Int.reverse)
scala> println(l_sort)
List(0, 1, 4, 6, 6)
scala> println(r_sort)
List(6, 6, 4, 1, 0)
// sortBy
scala> val sList = List("aa", "bb", "cc")
scala> val l_sortBy = sList.sortBy(_.chatAt(0))
scala> println(l_sortBy)
List(aa, bb, cc)
// sortWith
scala> val l_sortWith = list.sortWith(_ <= _)
scala> val r_sortWith = list.sortWith(_ >= _)
scala> println(l_sortWith)
List(0, 1, 4, 6, 6)
scala> println(r_sortWith)
List(6, 6, 4, 1, 0)
// case class 데이터 정렬
// correct가 같으면 index로 정렬
scala> case class Person(idx: Int, var correct: Int)
scala> val persons = Array(Person(1, 3), Person(2, 4), Person(3, 4)) scala> val list = persons.sortWith((x: Person, y: Person) => {
| if(x.correct == y.corrent)
| x.idx >= y.idx
| x.correct > y.correct
| }).toList
scala> println(list)
List(Person(2, 4), Person(3, 4), Person(1, 3))
Author And Source
이 문제에 관하여(Scala 스터디 3), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@youngss/Scala-스터디-3저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)