2012-08-27 52 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"})