2012-08-27 57 views

回答

144

利用partition方法:

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

你可能想看看scalex.org - 它允许你通过他们的签名搜索功能中阶标准库。例如,键入以下内容:

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

你会看到分区

+7

scalex.org域目前已经死亡。但有替代方案 - http://scala-search.org/--)。 – monnef

118

好,partition是你想要的东西 - 还有另一种方法,也使用谓词将列表分成两部分:span

第一个partition将把所有“true”元素放在一个列表中,其他元素放在第二个列表中。

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

11

如果你需要一些额外的东西,你也可以使用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来有效地保持这两个列表的顺序相同,但否则它就是我所需要的。 –

0

如果要拆分成列表超过2件,而忽视了界限,你可以使用这样的事情(修改,如果你需要搜索整数)

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