Comment diviser une séquence en deux morceaux par prédicat?

Comment diviser une séquence en deux listes par un prédicat?

Alternative: Je peux utiliser filter et filterNot , ou écrire ma propre méthode, mais n’y a-t-il pas une méthode plus générale (intégrée)?

En utilisant partition méthode de partition :

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

Bien que cette partition soit ce que vous vouliez, il existe une autre méthode qui utilise également un prédicat pour diviser une liste en deux: span .

Le premier, la partition , mettra tous les “vrais” éléments dans une liste et les autres dans la deuxième liste.

span mettra tous les éléments dans une liste jusqu’à ce qu’un élément soit “faux” (en termes de prédicat). À partir de ce moment, les éléments figureront dans la deuxième liste.

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

Vous voudrez peut-être jeter un oeil à scalex.org – il vous permet de rechercher des fonctions dans la bibliothèque standard scala par leur signature. Par exemple, tapez ce qui suit:

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

Vous verriez la partition .

Vous pouvez également utiliser foldLeft si vous avez besoin de quelque chose de plus. Je viens d’écrire un code comme celui-ci quand la partition ne l’a pas coupé:

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

Si vous voulez diviser une liste en plus de 2 pièces et ignorer les limites, vous pouvez utiliser quelque chose comme ça (modifiez si vous devez rechercher ints)

 def split(list_in: List[Ssortingng], search: Ssortingng): List[List[Ssortingng]] = { def split_helper(accum: List[List[Ssortingng]], list_in2: List[Ssortingng], search: Ssortingng): List[List[Ssortingng]] = { val (h1, h2) = list_in2.span({x: Ssortingng => 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: Ssortingng => x != "x"})