fbl*_*fbl 4 algorithm functional-programming scala partitioning
我真的不知道如何描述我在做什么,但这个例子应该有所帮助:
val vals = Array( (0, true),
(1, true),
(2,true),
(3,true),
(4,false),
(5, true),
(6, true),
(7, false),
(8, true),
(9,true))
Run Code Online (Sandbox Code Playgroud)
我希望识别每个"真实"区域中的第一个和最后一个元素,尽管在值更改时对数组进行分区也可以正常工作.我可以强制执行此操作,但在scala中执行此操作的最佳方法是什么?
如果您不介意添加一些基础设施来处理groupedWhile功能,您可以从Rex Kerr的扩展scala集合的答案中窃取.在答案的第二部分中使用处理数组的部分.
然后这是一件轻而易举的事:
scala> vals.groupedWhile(_._2 == _._2).filter(_.head._2 == true).map{g =>
(g.head, g.last)}.foreach(println)
((0,true),(3,true))
((5,true),(6,true))
((8,true),(9,true))
Run Code Online (Sandbox Code Playgroud)
编辑:
我提出了一个不需要的解决方案groupedWhile.它基于使用Iterator.iterate从种子开始并重复应用该span函数来提取具有相同布尔属性的下一组元素.在这种情况下,种子是下一组的元组,其余部分用于处理:
type Arr = Array[(Int, Boolean)] // type alias for easier reading
val res = Iterator.iterate[(Arr, Arr)]((Array(), vals)){ case (same, rest) =>
// repeatedly split in (same by boolean, rest of data)
// by using span and comparing against head
rest.span(elem => elem._2 == rest.head._2)
}.drop(1).takeWhile{ case (same, _) => // drop initial empty seed array
same.nonEmpty // stop when same becomes empty
}.collect{ case (same, _) if same.head._2 == true =>
// keep "true" groups and extract (first, last)
(same.head, same.last)
}.foreach(println) // print result
Run Code Online (Sandbox Code Playgroud)
其打印结果与上述相同.请注意,span对于空数组不会调用谓词,因此rest.head如果rest为空,则不会出现异常.