1

我正在计算列表中的 url 数量。为了实现这一点,我将添加到一个映射中,其中键是 url,值是当前计数器。每次遇到相同的键时,我都会增加计数器。这是代码:

    var m = new HashMap[String, Int]
    for(l <- MyList){
      val url = l.getUrl()
          var currentCount : Option[Int] = m.get(url)
          currentCount match {
                case Some(value) =>
                    var currentCount = value + 1
                    m = m ++ Map(url -> currentCount)
                case None =>
                    m = m ++ Map(url -> 1)
          }       
    }

我从一个不可变的映射开始,但发现每次都需要重新分配映射,以便使用关联的键来维护计数器值。是否有使用不可变地图完成与上述相同任务的解决方案?

4

4 回答 4

3

您可以执行以下操作:

MyList.groupBy(_.getUrl).map(i => (i._1, i._2.size))

那应该给你 am immutable Map,分组依据getUrl包含找到的次数getUrl

或者,为了清楚起见,使用类型签名:

val grouped Map[String, List[MyList]] = MyList.groupBy(_.getUrl)
grouped.map( i => (i._1, i._2.size)

正在发生的事情是groupBy将列表分组到一个映射中,其键是getUrl并且其值是List[MyList]每个项目getUrl等于键的位置。

下一行将通过返回列表的键和大小将 转换Map[String, List[MyList]]为 a 。Map[String, Int]映射的结构通常与(键,值)元组相同 - 因此在映射中,您可以相应地访问键和值。

于 2013-05-16T12:18:03.077 回答
1

您选择的可变 Map 方法非常适合给定的任务,并且应该在使用的空间和时间上超过大多数不可变的实现。你应该坚持下去。

将可变性保持在本地是一种很好的风格:

def calculateMap(myList : List[ URL? ]) : immutable.Map[String,Int] = {
  var m = new scala.collection.mutable.HashMap[String, Int]
  for{
     l <- myList
     url = l.getUrl()
    }{
      val currentCount = m.get(url) getOrElse 0
      m += (url -> currentCount + 1)
  }
  Map() ++ m // this transforms m in an immutable map
}

或者,如果您想提高速度并且 getUrl() 方法会阻塞,您可以尝试并行计算结果并将它们转换为如下图:

def calculateMapPar(myList : IndexedSeq[ URL? ]) : Map[String,Int] =
   myList.par.map(url => url.getUrl).groupBy(x => x).mapValues(_.size).seq
于 2013-05-16T13:20:01.427 回答
0

仅使用不可变映射:

    MyList.foldLeft(Map() : Map[String, Int]) { (map, elem) =>
      val key = elem.getUrl
      map + (key -> (map.getOrElse(key, 0) + 1))
    }
于 2013-05-17T04:57:58.600 回答
0

创建另一个可变的地图。并将其附加到另一个地图以获取新的可变地图。例如

val updatedMap = new HashMap[String, List[Employee]]
val merged = list.groupBy(_._1).map { case (k, v) => k -> v.map(_._2) }

val newMap = updatedMap ++ merged
于 2020-08-03T08:44:12.480 回答