Scala에서 불변 목록을 구성하는 방법은 여러 가지가 있습니다 (아래 인위적인 예제 코드 참조). 변경 가능한 ListBuffer를 사용하고, var
목록을 만들고 수정하고, 꼬리 재귀 방법을 사용하고 , 아마도 내가 모르는 다른 방법을 사용할 수 있습니다 .
본능적으로 ListBuffer를 사용하지만 그렇게 할 이유가 없습니다. 목록을 만드는 데 선호되는 방법이나 관용적 인 방법이 있습니까? 아니면 한 방법에 가장 적합한 상황이 있습니까?
import scala.collection.mutable.ListBuffer
// THESE are all the same as: 0 to 3 toList.
def listTestA() ={
var list:List[Int] = Nil
for(i <- 0 to 3)
list = list ::: List(i)
list
}
def listTestB() ={
val list = new ListBuffer[Int]()
for (i <- 0 to 3)
list += i
list.toList
}
def listTestC() ={
def _add(l:List[Int], i:Int):List[Int] = i match {
case 3 => l ::: List(3)
case _ => _add(l ::: List(i), i +1)
}
_add(Nil, 0)
}
답변
ListBuffer
일정 시간 추가 및 일정 시간 변환을 List
.
List
불변이며 일정한 시간 앞에 추가되고 선형 시간 추가가 있습니다.
목록을 구성하는 방법은 목록을 사용할 알고리즘과 목록을 생성 할 요소를 가져 오는 순서에 따라 다릅니다.
예를 들어, 사용할 때와 반대 순서로 요소를 가져 오면 a를 사용하고 List
앞에 추가 할 수 있습니다 . 꼬리 재귀 함수를 사용하든 foldLeft
또는 다른 것을 사용하든 실제로는 관련이 없습니다.
사용하는 것과 동일한 순서로 요소를 가져 ListBuffer
오면 성능이 중요하다면 a 가 가장 선호되는 선택입니다.
그러나, 당신은 중요한 경로에없는 및 입력이 충분히 낮은 경우 할 수 있습니다 항상 reverse
목록 이상 또는 단지 foldRight
또는 reverse
선형 시간 입력.
당신은 어떻게 하지 마십시오 할 IS는 사용 List
그것과 APPEND를. 이것은 당신에게 단지 앞뒤로 후진하는 것보다 훨씬 더 나쁜 성능을 줄 것입니다.
답변
그리고 간단한 경우 :
val list = List(1,2,3)
🙂
답변
음 .. 이건 너무 복잡해 보입니다. 제안해도 될까요
def listTestD = (0 to 3).toList
또는
def listTestE = for (i <- (0 to 3).toList) yield i
답변
일반적으로 모든 변수를 제거하여 Scala의 불변성에 초점을 맞추고 싶습니다. 가독성은 여전히 동료에게 중요하므로 :
시험:
scala> val list = for(i <- 1 to 10) yield i
list: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
대부분의 경우 목록으로 변환 할 필요조차 없습니다. 🙂
색인화 된 seq에는 필요한 모든 것이 있습니다.
즉, 이제 해당 IndexedSeq에서 작업 할 수 있습니다.
scala> list.foldLeft(0)(_+_)
res0: Int = 55
답변
저는 항상 List를 선호하고 “for comprehension”전에 “fold / reduce”를 사용합니다. 그러나 중첩 된 “폴드”가 필요한 경우 “for comprehension”이 선호됩니다. “fold / reduce / for”를 사용하여 작업을 수행 할 수없는 경우 재귀는 마지막 수단입니다.
그래서 당신의 예를 들어, 나는 할 것입니다.
((0 to 3) :\ List[Int]())(_ :: _)
내가하기 전에 :
(for (x <- 0 to 3) yield x).toList
참고 : “_”의 순서 때문에 여기에서 “foldLeft (/ :)”대신 “foldRight (: \)”를 사용합니다. StackOverflowException을 발생시키지 않는 버전의 경우 대신 “foldLeft”를 사용하십시오.
답변
사용 List.tabulate
과 같이,
List.tabulate(3)( x => 2*x )
res: List(0, 2, 4)
List.tabulate(3)( _ => Math.random )
res: List(0.935455779102479, 0.6004888906328091, 0.3425278797788426)
List.tabulate(3)( _ => (Math.random*10).toInt )
res: List(8, 0, 7)
답변
참고 :이 답변은 이전 버전의 Scala를 위해 작성되었습니다.
Scala 컬렉션 클래스는 Scala 2.8부터 재 설계 될 예정이므로 곧 목록을 만드는 방식을 변경할 준비를하십시오.
목록을 만드는 이전 버전과 호환되는 방법은 무엇입니까? 아직 2.8 문서를 읽지 않았기 때문에 전혀 모르겠습니다.