Augustine Ogundimu
Augustine Ogundimu

Reputation: 3

Why does this result in "type mismatch"?

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
    }

I get the following errors when I compile the code above.

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

Upvotes: 0

Views: 96

Answers (2)

sarveshseri
sarveshseri

Reputation: 13985

I am guessing that you are using that Map to maintain the count of occurrences each number in the array. And then you wan to return hight occurence count.

/**
  * @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)
}

But mutable things are really discouraged (unless required) in Scala world. So, here is the third way without using anything mutable.

/**
  * @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)
}

Or, you can choose the simplest solution,

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

Upvotes: 2

Puneeth Reddy V
Puneeth Reddy V

Reputation: 1578

Try like this myMap += ( value -> 1 ) instead of myMap += ( value, 1 )

You can even improve this block of code like

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

---OR---

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

Upvotes: 1

Related Questions