为什么会导致“类型不匹配”?

时间:2019-01-30 05:03:42

标签: scala

def migratoryBirds(arr: Array[Int]): Int = {

        //var A:Map[Char,Int] = Map()
        var myMap:Map[Int,Int] = Map()

        // looping over an array in 
        for(value <- arr){
            var total = myMap.get( value )
            if( total == None) {
                myMap += ( value, 1 )
            } else {
                myMap += ( value, ++total )
            }
        }

        var highest = 0
        var key = 0

        for ( (k,v) <- myMap ) {
            if ( v > highest ) {
                highest = v
                key = k
            }
        }

        highest
    }

编译上面的代码时出现以下错误。

Solution.scala:34: error: type mismatch;
 found   : Int
 required: (Int, Int)
                myMap += ( value, 1 )
                           ^
Solution.scala:34: error: type mismatch;
 found   : Int(1)
 required: (Int, Int)
                myMap += ( value, 1 )
                                  ^
Solution.scala:36: error: type mismatch;
 found   : Int
 required: (Int, Int)
                myMap += ( value, ++total )
                           ^
Solution.scala:36: error: not found: value ++
                myMap += ( value, ++total )
                                  ^
four errors found

2 个答案:

答案 0 :(得分:2)

我猜您正在使用那个Map来维护数组中每个数字的出现次数。然后您要返回高发生次数。

/**
  * @param sightIncidents Each Int "i" in the corresponds to one sighting of bird species "i"
  * @return tuple of bird species with the count of occurences for the most sighted bird
  */
def mostSightedMigratoryBird1(sightIncidents: Array[Int]): (Int, Int) = {
  // mutable reference but immutable map
  var map = scala.collection.immutable.Map.empty[Int, Int]

  sightIncidents.foreach(i => {
    val count = map.getOrElse(i, 0)
    val updatedCount = count + 1
    // since map is immutable, we create new map
    val newMapWithUpdatedCount = map + (i -> updatedCount)
    // we mutate the reference to point to new map
    map = newMapWithUpdatedCount
  })

  map.maxBy(_._2)
}

/**
  * @param sightIncidents Each Int "i" in the corresponds to one sighting of bird species "i"
  * @return tuple of bird species with the count of occurences for the most sighted bird
  */
def mostSightedMigratoryBird2(sightIncidents: Array[Int]): (Int, Int) = {
  // immutable reference but mutable map
  val map = scala.collection.mutable.Map.empty[Int, Int]

  sightIncidents.foreach(i => {
    val count = map.getOrElse(i, 0)
    val updatedCount = count + 1
    // we mutate the map by putting the updatedCount
    map += (i -> updatedCount)
    // it is not the += operator like other languages
    // it is actually a method
    // map.+=(i -> updatedCount)
  })

  map.maxBy(_._2)
}

但是在Scala世界中,真正不鼓励使用可变的东西(除非需要)。因此,这是不使用任何可变方法的第三种方法。

/**
  * @param sightIncidents Each Int "i" in the corresponds to one sighting of bird species "i"
  * @return tuple of bird species with the count of occurences for the most sighted bird
  */
def mostSightedMigratoryBird3(sightIncidents: Array[Int]): (Int, Int) = {
  // mutable reference and mutable map
  val emptyMap = scala.collection.immutable.Map.empty[Int, Int]

  val map = sightIncidents.foldLeft(emptyMap)({
    case (accMap, i) =>
      val count = accMap.getOrElse(i, 0)
      val updatedCount = count + 1
      val newMapWithUpdatedCount = map + (i -> updatedCount)
      newMapWithUpdatedCount
  })

  map.maxBy(_._2)
}

或者,您可以选择最简单的解决方案,

def mostSightedMigratoryBird2(sightIncidents: Array[Int]): (Int, Int) =
  sightIncidents
    .groupBy(i => i)
    .map({ case (i, group) => (i, group.size) })
    .maxBy(_._2)

答案 1 :(得分:1)

尝试myMap += ( value -> 1 )而不是myMap += ( value, 1 )

您甚至可以像这样改善代码段

for(value <- arr){
    val total = myMap.get( value )
    myMap += (value -> total.fold(1)(_ + 1 ) )
}

---或---

for(value <- arr){
    myMap += (value -> (myMap.getOrElse(value, 0) + 1))
}