Scala:集合中的连续id

时间:2015-08-18 14:00:15

标签: scala functional-programming set

我有一个类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
  }
}

但是,我不喜欢这个解决方案,因为我想避免这些变量,它是程序风格而不是功能风格。你能给我一个如何更好地做到这一点的提示吗?

2 个答案:

答案 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)