我在一个集合上进行并行运算,以计算列表中相同项目值的数量。这种情况下的列表是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)
你不能更新不可变集合,你所能做的就是将不可变集合与addition元素结合起来,得到新的不可变集合
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
。
@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
我认为您需要某种形式的MapReduce才能进行并行的项目数量估计。
在您的问题中,您已经拥有所有唯一的链接。映射的部分中间结果只是一对。而"reduce"就是toMap。因此,您可以简单地将链接映射到对(link->count),然后最终构建一个映射:
def count(iListVal:String) = listOfLinks.count(_.equalsIgnoreCase(iListVal))
val listOfPairs = uniqueSetOfLinks.par.map(iListVal => Try( (iListVal, count(iListVal)) ))
("地图"操作是标准地图)
然后删除异常:
val clearListOfPairs = listOfPairs.flatMap(_.toOption)
然后简单地将其转换为地图("reduce"):
val linkTotals = clearListOfPairs.toMap
(如果需要检查异常,请使用Try.failure)