Pregunta

Hi I am new in scala and I don't know how to change following code:

def makeProfil(listProfils: List[Profil]): List[Profil] ={

   // var newList = List[Profil]
          var ll = List[Map[Int,Profil]]()
   listProfils.foreach( item => {

     var count = item.czasOgladania.get
     if(item.czyKupil.get) count = count *4 ;
     if(item.czyPrzeczytal.get) count = count *3 ;
     if(item.czyWKarcie.get) count = count *2 ;
     ll ::= Map (count -> item) 
   } )

  }

I want to sort ll list by element count from and return sorted List[Profil] as the result. I tried various things but none of them work good.

¿Fue útil?

Solución

List has a method, sortWith, which sorts your list, where you can provide the criteria for sorting the list. The criteria is a function, accepting two arguments (two profiles), and result is Boolean, which indicates which one of them is "greater".

So, you can do the following:

ll.sortWith((p1, p2) => 
  getCount(p1) > getCount(p2)
)

where

def getCount(profil: Profil) = {
  var count = profil.czasOgladania.get
  if(profil.czyKupil.get) count = count *4 ;
  if(profil.czyPrzeczytal.get) count = count *3 ;
  if(profil.czyWKarcie.get) count = count *2 ;
  count
}

Update

BTW, it seems that profil.czasOgladania, profil.czyKupil etc., are Options. In that case you should first check if they are defined, and than perform computations. You may define default values, e.g.

// if profil.czasOgladania is defined, get the value. Else, return 10.
val count = profil.czasOgladania.getOrElse(10) 

or:

if(profil.czyWKarcie.getOrElse(false)) count = count *2

Otros consejos

Here's the whole thing without any mutable states (vars are bad practice). First you map the list of profiles to a list of (count, profile) tuples. The map doesn't seem necessary. Then you sort the list by the first item in the tuple, then map it to a list of profiles (the second item in the tuple).

def makeProfil(listProfils: List[Profil]): List[Profil] ={

    val profileCounts = listProfils.map( item => {
         val count = item.czasOgladania.getOrElse(0)
         val kupil = if(item.czyKupil.isDefined) 4 else 1
         val przeczytal = if(item.czyPrzeczytal.isDefined) 3 else 1;
         val wKarcie = if(item.czyWKarcie.isDefined) 2 else 1 ;
         val finalCount = count * kupil * przeczytal * wKarcie
         (count, item) 
    } )
    profileCounts.sortBy( _._1).map(_._2)
}

You can also use sortBy:

def makeProfil(listProfils: List[Profil]): List[Profil] = {
  def getCount(profil: Profil) = {
    var count = profil.czasOgladania.get
    if (profil.czyKupil.get) count *= 4
    if (profil.czyPrzeczytal.get) count *= 3
    if (profil.czyWKarcie.get) count *= 2
    count
  }

  listProfils.sortBy(p => getCount(p))
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top