수색…


목록 정렬

다음 목록 을 가정하면 다양한 방법으로 정렬 할 수 있습니다.

val names = List("Kathryn", "Allie", "Beth", "Serin", "Alana")

sorted() 의 기본 동작은 math.Ordering 을 사용하는 것입니다. math.Ordering 은 문자열의 경우 사전 식 정렬을 발생 시킵니다 .

names.sorted
// results in: List(Alana, Allie, Beth, Kathryn, Serin)

sortWith 사용하면 비교 함수를 사용하여 자신 만의 순서를 제공 할 수 있습니다.

names.sortWith(_.length < _.length)
// results in: List(Beth, Allie, Serin, Alana, Kathryn)

sortBy 사용하면 변형 함수를 제공 할 수 있습니다.

//A set of vowels to use
val vowels = Set('a', 'e', 'i', 'o', 'u')

//A function that counts the vowels in a name
def countVowels(name: String) = name.count(l => vowels.contains(l.toLower))

//Sorts by the number of vowels
names.sortBy(countVowels)
//result is: List(Kathryn, Beth, Serin, Allie, Alana)

`reverse :를 사용하여 항상 목록이나 정렬 된 목록을 뒤집을 수 있습니다.

names.sorted.reverse
//results in: List(Serin, Kathryn, Beth, Allie, Alana)

목록은 Java 메소드 java.util.Arrays.sort 및 스칼라 래퍼를 사용하여 정렬 될 수도 있습니다. scala.util.Sorting.quickSort

java.util.Arrays.sort(data)
scala.util.Sorting.quickSort(data)

컬렉션 변환 및 unboxing / boxing을 피할 수있는 경우 큰 컬렉션을 정렬 할 때 이러한 메서드는 성능을 향상시킬 수 있습니다. 성능 차이에 대한 자세한 내용은 Scala Collection 정렬, sortWith 및 sortBy 성능을 참조하십시오 .

n 개의 복사본을 포함하는 목록 만들기

어떤 객체 xn 복사본을 생성하려면 fill 메소드를 사용하십시오. 이 예제는 List 를 생성하지만 fill 이 의미가있는 다른 콜렉션에서도 작동 할 수 있습니다.

// List.fill(n)(x)
scala > List.fill(3)("Hello World")
res0: List[String] = List(Hello World, Hello World, Hello World)

목록 및 벡터 Cheatsheet

구현이 더 나은 성능을 가지기 때문에 이제는 List 대신 Vector 를 사용하는 것이 가장 좋습니다. 성능 특성은 여기에서 찾을 수 있습니다 . VectorList 가 사용되는 곳이면 어디서든지 사용할 수 있습니다.

목록 생성

List[Int]()         // Declares an empty list of type Int
List.empty[Int]     // Uses `empty` method to declare empty list of type Int
Nil                 // A list of type Nothing that explicitly has nothing in it

List(1, 2, 3)       // Declare a list with some elements
1 :: 2 :: 3 :: Nil  // Chaining element prepending to an empty list, in a LISP-style

원소를 가져 가라.

List(1, 2, 3).headOption // Some(1)
List(1, 2, 3).head       // 1

List(1, 2, 3).lastOption // Some(3)
List(1, 2, 3).last       // 3, complexity is O(n)

List(1, 2, 3)(1)         // 2, complexity is O(n)
List(1, 2, 3)(3)         // java.lang.IndexOutOfBoundsException: 4

요소 앞에 추가

0 :: List(1, 2, 3)       // List(0, 1, 2, 3)

요소 추가

List(1, 2, 3) :+ 4       // List(1, 2, 3, 4), complexity is O(n)

연결 (연결) 목록

List(1, 2) ::: List(3, 4) // List(1, 2, 3, 4)
List.concat(List(1,2), List(3, 4)) // List(1, 2, 3, 4)
List(1, 2) ++ List(3, 4)  // List(1, 2, 3, 4)

일반적인 작업

List(1, 2, 3).find(_ == 3)                     // Some(3)
List(1, 2, 3).map(_ * 2)                       // List(2, 4, 6)
List(1, 2, 3).filter(_ % 2 == 1)               // List(1, 3)
List(1, 2, 3).fold(0)((acc, i) => acc + i * i) // 1 * 1 + 2 * 2 + 3 * 3 = 14
List(1, 2, 3).foldLeft("Foo")(_ + _.toString)  // "Foo123"
List(1, 2, 3).foldRight("Foo")(_ + _.toString) // "123Foo"

지도 수집 Cheatsheet

map 메소드와는 다른 Map 유형의 콜렉션 작성에 대해 설명합니다.

지도 만들기

Map[String, Int]() 
val m1: Map[String, Int] = Map()
val m2: String Map Int = Map()

지도는 대부분의 작업에 대한 tuples 모음으로 간주 될 수 있습니다. 첫 번째 요소는 키이고 두 번째 요소는 값입니다.

val l = List(("a", 1), ("b", 2), ("c", 3))
val m = l.toMap                               // Map(a -> 1, b -> 2, c -> 3)

요소 가져 오기

val m = Map("a" -> 1, "b" -> 2, "c" -> 3)

m.get("a")  // Some(1)
m.get("d")  // None
m("a")      // 1
m("d")      // java.util.NoSuchElementException: key not found: d

m.keys      // Set(a, b, c)
m.values    // MapLike(1, 2, 3)

요소 추가

Map("a" -> 1, "b" -> 2) + ("c" -> 3)               // Map(a -> 1, b -> 2, c -> 3)
Map("a" -> 1, "b" -> 2) + ("a" -> 3)               // Map(a -> 3, b -> 2)
Map("a" -> 1, "b" -> 2) ++ Map("b" -> 3, "c" -> 4) // Map(a -> 1, b -> 3, c -> 4)

일반적인 작업

맵의 반복이 발생하는 작업 ( map , find , forEach 등)에서 컬렉션의 요소는 tuples 입니다. 함수 매개 변수는 튜플 접근 자 ( _1 , _2 ) 또는 case 블록이있는 부분 함수를 사용할 수 있습니다.

m.find(_._1 == "a")  // Some((a,1))
m.map {
  case (key, value) => (value, key)
}                    // Map(1 -> a, 2 -> b, 3 -> c)
m.filter(_._2 == 2)  // Map(b -> 2)
m.foldLeft(0){
  case (acc, (key, value: Int)) => acc + value
}                    // 6

컬렉션에 대한 맵핑 및 필터링

지도

컬렉션에서 '매핑'은지 map 함수를 사용하여 컬렉션의 각 요소를 유사한 방식으로 변환합니다. 일반적인 구문은 다음과 같습니다.

val someFunction: (A) => (B) = ???
collection.map(someFunction)

익명의 기능을 제공 할 수 있습니다.

collection.map((x: T) => /*Do something with x*/)

정수를 2로 곱하기

// Initialize 
val list = List(1,2,3)
// list: List[Int] = List(1, 2, 3)

// Apply map
list.map((item: Int) => item*2)
// res0: List[Int] = List(2, 4, 6)

// Or in a more concise way
list.map(_*2)
// res1: List[Int] = List(2, 4, 6)

필터

filter 는 컬렉션의 특정 요소를 제외하거나 '제외'할 때 사용됩니다. map 과 마찬가지로 일반 구문은 함수를 사용하지만 해당 함수는 Boolean 반환해야합니다.

val someFunction: (a) => Boolean = ???
collection.filter(someFunction)

익명 함수를 직접 제공 할 수 있습니다.

collection.filter((x: T) => /*Do something that returns a Boolean*/)

쌍 번호 확인

val list = 1 to 10 toList
// list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// Filter out all elements that aren't evenly divisible by 2
list.filter((item: Int) => item % 2==0)
// res0: List[Int] = List(2, 4, 6, 8, 10)

기타지도 및 필터 예제

case class Person(firstName: String,
                  lastName: String,
                  title: String)

// Make a sequence of people
val people = Seq(
  Person("Millie", "Fletcher", "Mrs"),
  Person("Jim", "White", "Mr"),
  Person("Jenny", "Ball", "Miss") )


// Make labels using map
val labels = people.map( person =>
  s"${person.title}. ${person.lastName}"
)

// Filter the elements beginning with J
val beginningWithJ = people.filter(_.firstName.startsWith("J"))

// Extract first names and concatenate to a string
val firstNames = people.map(_.firstName).reduce( (a, b) => a + "," + b )

스칼라 컬렉션 소개

스칼라 컬렉션 프레임 워크 는 저자에 따르면 사용하기 쉽고 간결하며 안전하고 빠르며 보편적으로 설계되었습니다.

프레임 워크는 콜렉션을 만들기위한 기본 요소로 설계된 스칼라 특성 으로 구성됩니다. 이러한 빌딩 블록에 대한 자세한 내용은 스칼라 컬렉션 개요를 참조하십시오 .

이러한 내장 콜렉션은 변경 불가능한 패키지와 변경 가능한 패키지로 구분됩니다. 기본적으로 변경 불가능한 버전이 사용됩니다. List() (아무것도 가져 오지 않고)를 작성하면 List() , 불변의 리스트가 작성됩니다.

프레임 워크의 가장 강력한 기능 중 하나는 같은 생각을 가진 컬렉션에서 일관되고 사용하기 쉬운 인터페이스입니다. 예를 들어 컬렉션의 모든 요소를 ​​합하는 작업은 List, Sets, Vectors, Seqs 및 Arrays에서 동일합니다.

val numList = List[Int](1, 2, 3, 4, 5)
numList.reduce((n1, n2) => n1 + n2)  // 15

val numSet = Set[Int](1, 2, 3, 4, 5)
numSet.reduce((n1, n2) => n1 + n2)   // 15

val numArray = Array[Int](1, 2, 3, 4, 5)
numArray.reduce((n1, n2) => n1 + n2) // 15

이러한 같은 생각을 가진 유형은 Traversable 특성을 상속합니다.

구현이 더 나은 성능을 가지기 때문에 이제는 List 대신 Vector 를 사용하는 것이 가장 좋습니다. 성능 특성은 여기에서 찾을 수 있습니다 . VectorList 가 사용되는 곳이면 어디서든지 사용할 수 있습니다.

이송 형

Traversable 특성을 가진 컬렉션 클래스는 foreach 구현하고 콜렉션에 대한 공통 연산을 수행하는 많은 메소드를 상속합니다. 컬렉션 클래스는 모두 동일하게 작동합니다. 가장 일반적인 작업은 다음과 같습니다.

  • Map - map , flatMapcollect 는 원래 컬렉션의 각 요소에 함수를 적용하여 새 컬렉션을 만듭니다.
List(1, 2, 3).map(num => num * 2) // double every number = List(2, 4, 6)

// split list of letters into individual strings and put them into the same list
List("a b c", "d e").flatMap(letters => letters.split(" ")) // = List("a", "b", "c", "d", "e")
  • 변환 - toList , toArray 및 기타 여러 변환 작업은 현재 컬렉션을보다 구체적인 컬렉션으로 변경합니다. 이것들은 일반적으로 'to'가 붙은 형식이고 더 구체적인 형식입니다 (즉, 'toList'가 List 변환됩니다).
val array: Array[Int] = List[Int](1, 2, 3).toArray // convert list of ints to array of ints
  • 크기 정보 - isEmpty , nonEmpty , sizehasDefiniteSize 는 집합에 대한 모든 메타 데이터입니다. 이렇게하면 컬렉션에 대한 조건부 작업 또는 컬렉션의 크기를 결정하는 코드 (무한 또는 불연속 여부 포함)가 허용됩니다.
List().isEmpty // true
List(1).nonEmpty // true
  • 요소 검색 - head , last , find 및 해당 Option 변형은 첫 번째 또는 마지막 요소를 검색하거나 컬렉션의 특정 요소를 찾는 데 사용됩니다.
val list = List(1, 2, 3)
list.head // = 1
list.last // = 3
  • 하위 컬렉션 검색 작업 - filter , tail , slice , drop 및 기타 작업을 통해 컬렉션의 일부를 선택하여 더 많은 작업을 수행 할 수 있습니다.
List(-2, -1, 0, 1, 2).filter(num => num > 0) // = List(1, 2)
  • 세부 작업 - partition , splitAt , spangroupBy 는 현재 컬렉션을 여러 부분으로 나눕니다.
// split numbers into < 0 and >= 0
List(-2, -1, 0, 1, 2).partition(num => num < 0) // = (List(-2, -1), List(0, 1, 2))
  • 요소 테스트 - exists , forallcount 는이 컬렉션을 검사하여 조건자를 충족시키는 지 확인하는 데 사용되는 연산입니다.
List(1, 2, 3, 4).forall(num => num > 0) // = true, all numbers are positive
List(-3, -2, -1, 1).forall(num => num < 0) // = false, not all numbers are negative

fold 메서드는 초기 누적 값을 사용하고 각 요소를 사용하여 누적 계산기를 성공적으로 업데이트하는 함수를 적용하여 컬렉션을 반복합니다.

val nums = List(1,2,3,4,5)
var initialValue:Int = 0;
var sum = nums.fold(initialValue){
  (accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 15 because 0+1+2+3+4+5 = 15

위의 예제에서 익명 함수는 fold() 에 제공되었습니다. 두 개의 인수를 취하는 명명 된 함수를 사용할 수도 있습니다. 이것을 가지고 다음과 같이 다시 쓸 수 있습니다 :

def sum(x: Int, y: Int) = x+ y
val nums = List(1, 2, 3, 4, 5)
var initialValue: Int = 0
val sum = nums.fold(initialValue)(sum)
println(sum) // prints 15 because 0 + 1 + 2 + 3 + 4 + 5 = 15

초기 값을 변경하면 결과에 영향을 미칩니다.

initialValue = 2;
sum = nums.fold(initialValue){ 
 (accumulator,currentElementBeingIterated) => accumulator + currentElementBeingIterated
}
println(sum) //prints 17 because 2+1+2+3+4+5 = 17

fold 메소드에는 foldLeftfoldRight 두 가지 변형이 있습니다.

foldLeft() 는 왼쪽에서 오른쪽으로 반복합니다 (컬렉션의 첫 번째 요소부터 마지막 ​​순서까지). foldRight() 는 오른쪽에서 왼쪽으로 반복됩니다 (마지막 요소에서 첫 번째 요소까지). fold()foldLeft() 처럼 왼쪽에서 오른쪽으로 반복합니다. 실제로 fold() 실제로 foldLeft() 내부적으로 호출합니다.

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

fold() , foldLeft()foldRight() 는 초기 값과 동일한 유형의 값을 반환합니다. 그러나, 달리 foldLeft()foldRight() 에 주어진 초기 값 fold() 은 동일한 종류 또는 컬렉션의 형태의 슈퍼 일 수있다.

이 예제에서는 순서가 관련이 없으므로 fold()foldLeft() 또는 foldRight() 로 변경하면 결과가 동일하게 유지됩니다. 주문에 민감한 기능을 사용하면 결과가 변경됩니다.

foldLeft() 경우 foldLeft() 보다 foldRight() 선호합니다. foldRight() 는 성능이 떨어집니다.

각각

foreach 는 결과를 반환하지 않는다는 점에서 컬렉션 이터레이터 중에서 특이합니다. 대신 부작용 만있는 각 요소에 함수를 적용합니다. 예 :

scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)

scala> x.foreach { println }
1
2
3

foreach 제공된 함수는 모든 반환 유형을 가질 수 있지만 결과는 무시됩니다 . 일반적으로 foreach 는 부작용이 바람직한 경우에 사용됩니다. 데이터를 변환하려면 map , filter , for comprehension 옵션 또는 다른 옵션 사용을 고려하십시오.

결과 폐기의 예

def myFunc(a: Int) : Int = a * 2
List(1,2,3).foreach(myFunc) // Returns nothing

줄이다

reduce() , reduceLeft()reduceRight 메소드는 폴드와 유사합니다. reduce에 전달 된 함수는 두 개의 값을 사용하고 세 번째 값을 산출합니다. 목록에서 작업 할 때 처음 두 값은 목록의 처음 두 값입니다. 함수의 결과와 목록의 다음 값은 함수에 다시 적용되어 새로운 결과를 산출합니다. 이 새로운 결과는 더 이상 요소가 없을 때까지 목록의 다음 값으로 적용됩니다. 최종 결과가 반환됩니다.

val nums = List(1,2,3,4,5)
sum = nums.reduce({ (a, b) => a + b })
println(sum) //prints 15

val names = List("John","Koby", "Josh", "Matilda", "Zac", "Mary Poppins")

def findLongest(nameA:String, nameB:String):String = {
  if (nameA.length > nameB.length) nameA else nameB
}

def findLastAlphabetically(nameA:String, nameB:String):String = {
  if (nameA > nameB) nameA else nameB
}

val longestName:String = names.reduce(findLongest(_,_))
println(longestName) //prints Mary Poppins

//You can also omit the arguments if you want
val lastAlphabetically:String = names.reduce(findLastAlphabetically)
println(lastAlphabetically) //prints Zac

접기 기능과 비교하여 축소 기능이 작동하는 방식에는 몇 가지 차이점이 있습니다. 그들은:

  1. reduce 함수에는 초기 누적 기 값이 없습니다.
  2. 빈 목록에서는 함수를 호출 할 수 없습니다.
  3. 줄이기 함수는 목록의 유형 또는 수퍼 유형 만 리턴합니다.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow