2015-08-18 14 views
3

我有一个类Edge(如图中所示),并带有以下签名。Scala:集合中的连续id

class Edge(b1: Block, b2: Block, var id: Int, arity: Int) 

Block是一类 - 它做什么,没有意思。

现在,已经有一组s与一些提供源和目标的对象。我现在想给这些边缘一个连续的id(从1开始,下一个block将得到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 
    } 
} 

但是,因为我想避免这些变量我不喜欢这样的解决方案,它是程序式的,而不是功能性的风格。你能给我一个提示,我怎么能做得更好?

回答

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开始,下一个块应得到2,依此类推......)。 '请注意''zipWithIndex'从**索引0 **开始。 –

+0

谢谢你,很好的解决方案。 –

1

以类似的方式与zipWithIndex但是从给定的初始值开始,用Stream1开始,例如如下荏苒,

val edges = for ((e,id) <- s zip Stream.from(1)) yield 
       new Edge(e.getSrcBlock, e.getDstBlock, id, getArity(e)) 

通过将伴随对象与Edge关联的apply方法将值用于构造Edge实例,我们获得了更多readab乐代码,

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) 
+0

太棒了!非常感谢。我喜欢! –