Je viens d'avoir un cas d'utilisation où je devais diviser une liste en n sous-listes, de sorte que les éléments sont pris dans l'ordre de la liste originale et groupés alors que le prédicat est vrai sous-liste (lorsqu'elle est fausse, une nouvelle sous-liste est lancée). Je n'ai pas trouvé cette fonctionnalité dans la bibliothèque standard, et j'ai pensé que c'était un bon exercice pour essayer de le résoudre dans un style fonctionnel (car je suis loin d'un gourou fonctionnel).Scala: scinder une liste en utilisant un prédicat pour les sous-listes
Voici le code que j'ai trouvé. Mais je pense que cela peut être amélioré beaucoup. Pouvez-vous m'aider à trouver une meilleure façon de coder cela?
class ListWithSplitter[A](val theList:List[A])
{
private def sublistWhile(list:List[A], pred:(List[A] => Boolean)):(List[A],List[A]) =
{
def combine(okList:List[A], remaining:List[A], pred:(List[A] => Boolean)):(List[A],List[A]) =
{
if(pred(okList ::: remaining.head :: Nil))
combine(okList ::: remaining.head :: Nil, remaining.tail, pred)
else
(okList, remaining)
}
list match {
case Nil => (Nil, Nil)
case x :: Nil => (list, Nil)
case x :: xs => combine(List(x), xs, pred)
}
}
private def combinedSplit(list:List[A], pred:(List[A] => Boolean)):List[List[A]] =
{
val r = sublistWhile(list, pred)
r match {
case (Nil, Nil) => List(Nil)
case (x, Nil) => List(x)
case (x, y) => x :: combinedSplit(y, pred)
}
}
def combinedSplit(pred:(List[A] => Boolean)):List[List[A]] =
{
combinedSplit(theList, pred)
}
}
trait ListCombinedSplit
{
implicit def list2combSplitter[A](x:List[A]) : ListWithSplitter[A] = new ListWithSplitter(x)
}
object ListSplitter extends ListCombinedSplit {
def main(args:Array[String])
{
// sample usage: sum of each sublist is less than 100
val a = List(4, 59, 10, 24, 42, 9, 2, 44, 44, 44, 44)
val b = a combinedSplit { list:List[Int] => ((0 /: list)(_ + _)) < 100 }
b foreach println
}
}
Résultat d'échantillon est:
List(4, 59, 10, 24)
List(42, 9, 2, 44)
List(44, 44)
List(44)
Merci ... pas aussi générique que je l'avais prévu mais fera pour mon cas d'utilisation! –