복붙노트

[SCALA] 스칼라 목록을 만들 수있는 좋은 방법

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)
}

해결법

  1. ==============================

    1.ListBuffer는 목록에 일정 시간 APPEND하고, 일정 시간의 변환이 변경 가능한 목록입니다.

    ListBuffer는 목록에 일정 시간 APPEND하고, 일정 시간의 변환이 변경 가능한 목록입니다.

    목록은 불변이며, 일정 시간의 앞에 추가 및 선형 시간 APPEND 있습니다.

    귀하의 목록에있는 알고리즘에 따라 어떻게 구성 당신의 목록과 요소가 그것을 만들 수있는 순서를 사용합니다.

    당신은 그들이 사용하려고 할 때의 반대 순서의 요소를 얻을 경우 예를 들어, 당신은 단지 목록을 사용하여 앞에 추가 할 수 있습니다. 당신이 꼬리 재귀 함수, foldLeft, 또는 다른 뭔가 그렇게 할 것입니다 여부는 정말 관련이 없습니다.

    당신은 당신이 그들을 사용하는 것과 동일한 순서로 요소를 얻는 경우에 성능이 중요한 경우, 다음 ListBuffer는 가장 가능성이 바람직한 선택이 될 것입니다.

    당신이 중요한 경로에없는 및 입력이 충분히 낮은 경우 그러나, 당신은 항상 나중에 목록을 리버스, 아니면 그냥 foldRight, 또는 선형 시간 입력을 취소 할 수 있습니다.

    당신이 할하지 마십시오 것은 그것에 목록 및 APPEND를 사용합니다. 이렇게하면 바로 앞에 추가하고 마지막에 반전보다 훨씬 더 성능을 제공 할 것입니다.

  2. ==============================

    2.그리고 간단한 경우에 :

    그리고 간단한 경우에 :

    val list = List(1,2,3) 
    

    :)

  3. ==============================

    3.Uhmm ..이 나에게 너무 복잡 보인다. 내가 제안 할 수있다

    Uhmm ..이 나에게 너무 복잡 보인다. 내가 제안 할 수있다

    def listTestD = (0 to 3).toList
    

    또는

    def listTestE = for (i <- (0 to 3).toList) yield i
    
  4. ==============================

    4.당신은 일반적으로 어떤 바르를 제거하여 스칼라의 불변성에 집중하고 싶어요. 가독성은 여전히 ​​동료 사람을 위해 중요하다 :

    당신은 일반적으로 어떤 바르를 제거하여 스칼라의 불변성에 집중하고 싶어요. 가독성은 여전히 ​​동료 사람을 위해 중요하다 :

    시험:

    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)
    

    당신은 아마 대부분의 경우에 목록을 변환 할 필요가 없습니다 :)

    인덱싱 된 서열은 당신이 필요로하는 모든 것을해야합니다 :

    즉, 당신이 할 수 IndexedSeq에 지금 일 :

    scala> list.foldLeft(0)(_+_)
    res0: Int = 55
    
  5. ==============================

    5.나는 항상 목록을 선호하는 나는 "/ 배 감소" "이해는"전에 사용합니다. 그러나 "이해는"중첩는 "주름"경우 선호 필요합니다. 내가 "에 대한 / 감소 / 배"를 사용하여 작업을 수행 할 수없는 경우 재귀는 최후의 수단이다.

    나는 항상 목록을 선호하는 나는 "/ 배 감소" "이해는"전에 사용합니다. 그러나 "이해는"중첩는 "주름"경우 선호 필요합니다. 내가 "에 대한 / 감소 / 배"를 사용하여 작업을 수행 할 수없는 경우 재귀는 최후의 수단이다.

    그래서 당신의 예를 들어, 내가 할 것입니다 :

    ((0 to 3) :\ List[Int]())(_ :: _)
    

    내가 전에해야 :

    (for (x <- 0 to 3) yield x).toList
    

    참고 : 나는 "(: \) foldRight"를 사용하는 대신 "foldLeft을 (/ :"여기 때문에 "_"의 순서의. 대신, "foldLeft을"있는 StackOverflowException를 포기하지 않는 버전하십시오.

  6. ==============================

    6.이 같은 List.tabulate를 사용하여,

    이 같은 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)
    
  7. ==============================

    7.참고 :이 답변은 스칼라가 이전 버전 용으로 작성됩니다.

    참고 :이 답변은 스칼라가 이전 버전 용으로 작성됩니다.

    스칼라 컬렉션 클래스 그래서 당신은 곧 목록을 생성하는 방법을 변경할 수 있도록 준비 스칼라 2.8으로 재 설계 될 것입니다.

    목록을 만드는 전방 호환 방법은 무엇입니까? 나는 아직 2.8 문서를 읽을 수 있지 않기 때문에 나는 아무 생각이 없습니다.

    컬렉션 클래스의 제안 된 변경 사항을 설명하는 PDF 문서

  8. ==============================

    8.새로운 스칼라 개발자로서 나는 위의 제안 방법과 목록 작성 시간을 확인하는 작은 테스트를 썼다. toList 가장 빠른 방법 - 그것은 (X (0)) 수익률 p 용 (P <)처럼 보인다.

    새로운 스칼라 개발자로서 나는 위의 제안 방법과 목록 작성 시간을 확인하는 작은 테스트를 썼다. toList 가장 빠른 방법 - 그것은 (X (0)) 수익률 p 용 (P <)처럼 보인다.

    import java.util.Date
    object Listbm {
    
      final val listSize = 1048576
      final val iterationCounts = 5
      def getCurrentTime: BigInt = (new Date) getTime
    
      def createList[T] ( f : Int => T )( size : Int ): T = f ( size )
    
      // returns function time execution
      def experiment[T] ( f : Int => T ) ( iterations: Int ) ( size :Int ) : Int  = {
    
        val start_time = getCurrentTime
        for ( p <- 0 to iterations )  createList ( f ) ( size )
        return (getCurrentTime - start_time) toInt
    
      }
    
      def printResult ( f:  => Int ) : Unit = println ( "execution time " + f  )
    
      def main( args : Array[String] ) {
    
    
        args(0) match {
    
          case "for" =>  printResult ( experiment ( x => (for ( p <- ( 0 to x ) ) yield p) toList  ) ( iterationCounts ) ( listSize ) )
          case "range"  =>  printResult ( experiment ( x => ( 0 to x ) toList ) ( iterationCounts ) ( listSize ) )
          case "::" => printResult ( experiment ( x => ((0 to x) :\ List[Int]())(_ :: _) ) ( iterationCounts ) ( listSize ) )
          case _ => println ( "please use: for, range or ::\n")
        }
      }
    }
    
  9. ==============================

    9.collection.breakOut를 사용하여 단지 예시

    collection.breakOut를 사용하여 단지 예시

    scala> val a : List[Int] = (for( x <- 1 to 10 ) yield x * 3)(collection.breakOut)
    a: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)
    
    scala> val b : List[Int] = (1 to 10).map(_ * 3)(collection.breakOut)
    b: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)
    
  10. ==============================

    10.문자열의 목록을 만들려면 다음을 사용 :

    문자열의 목록을 만들려면 다음을 사용 :

    val l = List("is", "am", "are", "if")
    
  11. from https://stackoverflow.com/questions/1241166/preferred-way-to-create-a-scala-list by cc-by-sa and MIT license