목록을 요소 수가 고정된 여러 목록으로 분할
요소 목록을 최대 N개의 항목이 있는 목록으로 분할하려면 어떻게 해야 합니까?
예: 7개의 요소가 있는 목록을 지정하면 4개의 그룹으로 구성된 그룹을 만듭니다. 마지막 그룹에는 요소가 적을 수 있습니다.
split(List(1,2,3,4,5,6,"seven"),4)
=> List(List(1,2,3,4), List(5,6,"seven"))
내 생각에 당신은grouped
반복기를 반환하지만 결과를 목록으로 변환할 수 있습니다.
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))
슬라이딩 방식을 사용하여 작업을 수행하는 훨씬 쉬운 방법이 있습니다.다음과 같이 동작합니다.
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))
직접 만들고 싶은 경우:
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))
edit: 2년 후에 이것을 확인했을 때, 저는 이 구현을 추천하지 않습니다.size
는 O(n)입니다.따라서 이 방법은 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)
}
테일 재귀 대 재귀에 대한 논의가 있었기 때문에 분할 방식의 테일 재귀 버전을 추가합니다.tailrec 주석을 사용하여 구현이 실제로 tail-recusive가 아닌 경우에 컴파일러가 불만을 제기하도록 했습니다.테일 재귀는 후드 아래에서 루프가 되어 버리기 때문에 스택이 무한히 늘어나지 않기 때문에 큰 리스트에서도 문제가 발생하지 않는다고 생각합니다.
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)
}
이것은 take/drop이 아닌 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)
언급URL : https://stackoverflow.com/questions/7459174/split-list-into-multiple-lists-with-fixed-number-of-elements
'programing' 카테고리의 다른 글
이 블록에서 자신을 강하게 포착하는 것은 유지 사이클로 이어질 수 있다 (0) | 2023.04.19 |
---|---|
고유 엔트리가 있는 두 목록 간의 차이점 가져오기 (0) | 2023.04.19 |
CMD가 Administrator로 실행 중인지, 상승된 권한을 가지고 있는지를 검출하는 방법 (0) | 2023.04.19 |
vba를 사용하여 다른 워크북에 시트를 복사하는 방법 (0) | 2023.04.19 |
악센트 문자가 포함된 클립보드에서 CSV 데이터 가져오기(Excel에서 붙여넣기) (0) | 2023.04.19 |