Reputation: 229
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.
Upvotes: 0
Views: 111
Reputation: 4182
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)
}
Upvotes: 1
Reputation: 1285
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 Option
s. 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
Upvotes: 1
Reputation: 722
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))
}
Upvotes: 0