술어로 시퀀스를 두 조각으로 나누는 방법은 무엇입니까?


120

술어별로 시퀀스를 두 개의 목록으로 분할하려면 어떻게해야합니까?

대안 : filterand 를 사용 filterNot하거나 나만의 방법을 작성할 수 있지만 더 일반적인 (내장) 방법이 없습니까?

답변:


193

partition방법 을 사용하여 :

scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))

1
val (even, odd) = List(1,2,3,4).partition(x => x % 2 == 0)결과 튜플을 partition읽기 쉬운 방식 으로 파괴하는 방법입니다.
k0pernikus

2
파티션 내부의 기능을 _ % 2 == 0.
k0pernikus

138

좋은 partition당신이 원하는 건이었다가 - 또한 두 목록을 분할하는 술어를 사용하는 다른 방법이있다 : span.

첫 번째, 파티션 은 모든 "진정한"요소를 하나의 목록에, 나머지는 두 번째 목록에 넣습니다.

span 은 요소가 "false"(술어 측면에서)가 될 때까지 모든 요소를 ​​하나의 목록에 넣습니다. 그 시점부터 두 번째 목록에 요소를 넣습니다.

scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))

2
내가 찾던 바로 그것. 목록이 관련 기준에 따라 정렬되면 훨씬 더 의미가 있습니다.
erich2k8 2013

16

scalex.org를 살펴보고 싶을 수도 있습니다. 이를 통해 스칼라 표준 라이브러리에서 서명으로 함수를 검색 할 수 있습니다. 예를 들어, 다음을 입력하십시오.

List[A] => (A => Boolean) => (List[A], List[A])

파티션 이 표시 됩니다 .


10
scalex.org 도메인은 현재 죽었습니다. 그러나 대안이 있습니다 -scala-search.org ;-).
monnef

1
물고기 잡는 법을 가르치다!
이 사용자는 도움이 필요합니다.

1
@monnef 2020 년 대안에 대한 대안이 있습니까? :)
tehCivilian

14

조금 더 필요한 경우 foldLeft를 사용할 수도 있습니다. 파티션이 잘리지 않았을 때 다음과 같은 코드를 작성했습니다.

val list:List[Person] = /* get your list */
val (students,teachers) = 
  list.foldLeft(List.empty[Student],List.empty[Teacher]) {
    case ((acc1, acc2), p) => p match {
      case s:Student => (s :: acc1, acc2)
      case t:Teacher  => (acc1, t :: acc2)
    }
  }

1
튜플과 foldLeft를 사용하는 아주 좋은 방법입니다. 나는 ListBuffer를 사용하여 두 목록을 동일한 순서로 효율적으로 유지했지만 그렇지 않으면 내가 필요한 것을 찾았습니다.
Matt Hagopian 2014 년

1

내가 파티에 늦을 수도 있고 더 구체적인 답변이 있다는 것을 알고 있지만, groupBy

val ret = List(1,2,3,4).groupBy(x => x % 2 == 0)

ret: scala.collection.immutable.Map[Boolean,List[Int]] = Map(false -> List(1, 3), true -> List(2, 4))

ret(true)
res3: List[Int] = List(2, 4)

ret(false)
res4: List[Int] = List(1, 3)

이렇게하면 조건을 부울이 아닌 것으로 변경해야하는 경우 코드가 미래에 대비할 수 있습니다.


0

목록을 2 개 이상으로 나누고 경계를 무시하려면 다음과 같이 사용할 수 있습니다 (int를 검색해야하는 경우 수정).

def split(list_in: List[String], search: String): List[List[String]] = {
  def split_helper(accum: List[List[String]], list_in2: List[String], search: String): List[List[String]] = {
    val (h1, h2) = list_in2.span({x: String => x!= search})
    val new_accum = accum :+ h1
    if (h2.contains(search)) {
      return split_helper(new_accum, h2.drop(1), search) 
    }
    else {
    return accum
    }
  }
  return split_helper(List(), list_in, search)
}

// TEST

// split(List("a", "b", "c", "d", "c", "a"), {x: String => x != "x"})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.