获取对不可变Map的引用

时间:2013-08-08 12:20:43

标签: scala

我正在对一个集合进行并行化,以计算List中相同项目值的数量。这种情况下的列表是uniqueSetOfLinks:

for (iListVal <- uniqueSetOfLinks.par) {
  try {
      val num : Int = listOfLinks.count(_.equalsIgnoreCase(iListVal))
      linkTotals + iListVal -> num
  }
  catch {
  case e : Exception => {
   e.printStackTrace() 
  }
  }
}

linkTotals是一个不可变的Map。要获得对链接总数的引用,我需要更新linkTotals以使其不可变吗?

然后我可以做类似的事情:

linkTotals.put(iListVal, num)

3 个答案:

答案 0 :(得分:3)

你无法更新不可变集合,你所能做的就是将不可变集合与add元素结合起来获取新的不可变集合,如下所示:

val newLinkTotals = linkTotals + (iListVal -> num)

如果是收集,您可以创建新的对集合,然后将所有对添加到地图中:

val optPairs =
  for (iListVal <- uniqueSetOfLinks.par)
    yield
      try {
        val num : Int = listOfLinks.count(_.equalsIgnoreCase(iListVal))
        Some(iListVal -> num)
      }
      catch {
        case e : Exception =>  e.printStackTrace()
        None
      }


val newLinkTotals = linkTotals ++ optPairs.flatten // for non-empty initial map
val map = optPairs.flatten.toMap // in case there is no initial map

请注意,您使用的是并行集合(.par),因此不应使用可变状态,例如linkTotals += iListVal -> num

答案 1 :(得分:1)

@ senia答案的可能变化(摆脱明确的flatten):

val optPairs =
  (for {
    iListVal <- uniqueSetOfLinks.par
    count <- {
      try
        Some(listOfLinks.count(_.equalsIgnoreCase(iListVal)))
      catch {
        case e: Exception =>
          e.printStackTrace()
          None
      }
    }
  } yield iListVal -> count) toMap

答案 2 :(得分:0)

我认为您需要某种形式的MapReduce才能对并行数量的项目进行估算。

在您的问题中,您已拥有所有唯一链接。地图的部分中间结果只是一对。而“减少”只是地图。所以你可以简单地将链接映射到配对(link-&gt; count),然后最终构建一个地图:

def count(iListVal:String) = listOfLinks.count(_.equalsIgnoreCase(iListVal))
val listOfPairs = uniqueSetOfLinks.par.map(iListVal => Try( (iListVal, count(iListVal)) ))

(“map”操作是par-map)

然后删除例外:

val clearListOfPairs = listOfPairs.flatMap(_.toOption)

然后只需将其转换为地图(“减少”):

val linkTotals = clearListOfPairs.toMap

(如果您需要检查异常,请使用Try.failure)