복붙노트

[SCALA] 요소의 고정 된 수의 여러 목록으로 분할 목록

SCALA

요소의 고정 된 수의 여러 목록으로 분할 목록

어떻게 대부분의 N 항목에 함께리스트에 요소의 목록을 분할하려면?

예는 : 7 개 요소 목록을 감안할 때, 더 적은 요소 아마도 마지막 그룹을 떠나 4의 그룹을 만들 수 있습니다.

split(List(1,2,3,4,5,6,"seven"),4)

=> List(List(1,2,3,4), List(5,6,"seven"))

해결법

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

    1.난 당신이 그룹화를 찾고 생각합니다. 그것은 반복자를 반환하지만 당신이 목록에 결과를 변환 할 수 있습니다,

    난 당신이 그룹화를 찾고 생각합니다. 그것은 반복자를 반환하지만 당신이 목록에 결과를 변환 할 수 있습니다,

    scala> List(1,2,3,4,5,6,"seven").grouped(4).toList
    res0: List[List[Any]] = List(List(1, 2, 3, 4), List(5, 6, seven))
    
  2. ==============================

    2.슬라이딩 방법을 사용하여 작업을 할 수있는 더 쉬운 방법이있다. 그것은이 방식으로 작동합니다 :

    슬라이딩 방법을 사용하여 작업을 할 수있는 더 쉬운 방법이있다. 그것은이 방식으로 작동합니다 :

    val numbers = List(1, 2, 3, 4, 5, 6 ,7)
    

    당신이 크기 3의 작은 목록으로 목록을 휴식하고 싶은 말은 수 있습니다.

    numbers.sliding(3, 3).toList
    

    당신에게 줄 것이다

    List(List(1, 2, 3), List(4, 5, 6), List(7))
    
  3. ==============================

    3.아니면 자신을하려는 경우 :

    아니면 자신을하려는 경우 :

    def split[A](xs: List[A], n: Int): List[List[A]] = {
      if (xs.size <= n) xs :: Nil
      else (xs take n) :: split(xs drop n, n)
    }
    

    사용하다:

    scala> split(List(1,2,3,4,5,6,"seven"), 4)
    res15: List[List[Any]] = List(List(1, 2, 3, 4), List(5, 6, seven))
    

    편집 : (가) 내장 방법은 빨리 큰 목록에 대한하게 이유를 설명 할 수 O (N ^ 2), 크기는 O (N)이며, 따라서이 방법이기 때문에 2 년 후이 검토에 따라,이 구현을 권하고 싶지 않다 아래와 같이 의견에 주목했다. 다음과 같이 효율적으로 구현할 수 있습니다 :

    def split[A](xs: List[A], n: Int): List[List[A]] =
      if (xs.isEmpty) Nil 
      else (xs take n) :: split(xs drop n, n)
    

    또는 (약간) 더 효율적으로 splitAt를 사용하여 :

    def split[A](xs: List[A], n: Int): List[List[A]] =
      if (xs.isEmpty) Nil 
      else {
        val (ys, zs) = xs.splitAt(n)   
        ys :: split(zs, n)
      }
    
  4. ==============================

    4.재귀 대 꼬리 재귀의 논의가있을 때부터 분할 방법의 꼬리 재귀 버전을 추가하고있다. 나는 구현이 실제로 꼬리 recusive없는 경우에 불평 컴파일러를 강제로 tailrec 주석을 사용했다. 꼬리 재귀 나는 후드 루프에 회전을 믿고 따라서도 큰 목록에 대한 문제는 스택 무한정 증가하지 않을 것 같은 원인.

    재귀 대 꼬리 재귀의 논의가있을 때부터 분할 방법의 꼬리 재귀 버전을 추가하고있다. 나는 구현이 실제로 꼬리 recusive없는 경우에 불평 컴파일러를 강제로 tailrec 주석을 사용했다. 꼬리 재귀 나는 후드 루프에 회전을 믿고 따라서도 큰 목록에 대한 문제는 스택 무한정 증가하지 않을 것 같은 원인.

    import scala.annotation.tailrec
    
    
    object ListSplitter {
    
      def split[A](xs: List[A], n: Int): List[List[A]] = {
        @tailrec
        def splitInner[A](res: List[List[A]], lst: List[A], n: Int) : List[List[A]] = {
          if(lst.isEmpty) res
          else {
            val headList: List[A] = lst.take(n)
            val tailList : List[A]= lst.drop(n)
            splitInner(headList :: res, tailList, n)
          }
        }
    
        splitInner(Nil, xs, n).reverse
      }
    
    }
    
    object ListSplitterTest extends App {
      val res = ListSplitter.split(List(1,2,3,4,5,6,7), 2)
      println(res)
    }
    
  5. ==============================

    5.나는이 대신 테이크 / 드롭의 splitAt를 사용하여 구현 생각

    나는이 대신 테이크 / 드롭의 splitAt를 사용하여 구현 생각

    def split [X] (n:Int, xs:List[X]) : List[List[X]] =
        if (xs.size <= n) xs :: Nil
        else   (xs.splitAt(n)._1) :: split(n,xs.splitAt(n)._2)
    
  6. from https://stackoverflow.com/questions/7459174/split-list-into-multiple-lists-with-fixed-number-of-elements by cc-by-sa and MIT license