我有一个类Edge
(如图中所示),带有以下签名。
class Edge(b1: Block, b2: Block, var id: Int, arity: Int)
Block
是一个类 - 它的作用,并不有趣。
现在,已经存在一组s
,其中包含一些提供源和目标的对象。我现在想给这些边带一个连续的id(从1开始,下一个块应该得到2,依此类推......)。
我目前通过首先将所有1作为id来执行此操作,之后我运行了一个重新分配标签的函数createLabels
。(参见下文)。
val edges = s map { x => new Edge(x.getSrcBlock, x.getDstBlock, 1, getArity(x))}
def createLabels: Unit = {
var i: Int = 0
for(e <- edges) {
e.id = i
i = i+1
}
}
但是,我不喜欢这个解决方案,因为我想避免这些变量,它是程序风格而不是功能风格。你能给我一个如何更好地做到这一点的提示吗?
答案 0 :(得分:5)
您可以使用zipWithIndex
:
case class Edge(b1: Block, b2: Block, id: Int, arity: Int)
val edges = s.zipWithIndex.map { case (x, index) =>
Edge(x.getSrcBlock, x.getDstBlock, index, getArity(x))
}
答案 1 :(得分:1)
以与zipWithIndex
类似的方式,但从给定的初始值开始,使用从Stream
开始的1
进行压缩,例如,如下所示,
val edges = for ( (e,id) <- s zip Stream.from(1) ) yield
new Edge(e.getSrcBlock, e.getDstBlock, id, getArity(e))
通过将带有用于构造Edge
实例的值的apply方法与Edge
相关联,我们可以获得更易读的代码,
class Edge(b1: Block, b2: Block, var id: Int, arity: Int)
object Edge {
def apply(id: Int, e: SrcDstData) = {
new Edge(e.getSrcBlock, e.getDstBlock, id, getArity(e))
}
}
因此
val edges = for ( (e,id) <- s zip Stream.from(1)) yield Edge(id,e)