我已经实现了一个循环遍历列表的函数,并为我提供了另一个包含预期结果的List。
我使用的是以下方法:
案例类
case class Node(key:Int,
children:List[Node] = Nil,
valid:Option[Boolean] = Some(false))
功能
def ranking(nodes:List[Node]): List[Score] = {
def rankingChildren(node: Node, score: Double = 0, depth: Int = 0): Double =
node.children.filter(n => n.valid == Some(true)).foldLeft(score)((acc, n) =>
rankingChildren(n, acc + 1, depth + 1))
nodes.headOption.map(node => {
val ns = Score(node.key, rankingChildren(node)) :: ranking(nodes.tail)
ns ::: ranking(node.children)
}).getOrElse(Nil)
}.sortBy(s => (- s.score, + s.customer))
这部分代码看起来有些奇怪,因为我认为我可以使用fold函数编写相同的东西,而不是使用tail调用。
nodes.headOption.map(node => {
val ns = Score(node.key, rankingChildren(node)) :: ranking(nodes.tail)
ns ::: ranking(node.children)
}).getOrElse(Nil)
所以我开始使用折叠编写并卡住了:
nodes.foldLeft(List[Score]())((acc, n) =>
Score(n.key, rankingChildren(n)) :: acc
)
仅添加第一个节点,子列表未添加到结果列表中。
可以用fold折叠headOption.map吗?
EDIT1:
我使用了:
nodes.foldLeft(List[Score]())((acc, n) =>
(Score(n.key, rankingChildren(n)) :: acc) ::: ranking(n.children)
)
ranking()函数是递归的。尾递归比较糟糕吗?我用headOption.map编写的解决方案是个坏主意?