列表[Map [Int,Object]]排序

时间:2014-05-11 16:26:43

标签: scala

您好我是scala的新手,我不知道如何更改以下代码:

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) 
   } )

  }

我希望按元素计数排序 ll ,并返回排序后的List [Profil]作为结果。我尝试了各种各样的东西,但没有一个能很好用。

3 个答案:

答案 0 :(得分:1)

List有一个方法sortWith,可以对列表进行排序,您可以在其中提供排序列表的条件。标准是一个函数,接受两个参数(两个配置文件),结果是布尔值,表示其中哪一个是"更大"。

因此,您可以执行以下操作:

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

其中

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
}

<强>更新

顺便说一句,profil.czasOgladaniaprofil.czyKupil等似乎是Option。在这种情况下,您应首先检查它们是否已定义,然后执行计算。您可以定义默认值,例如

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

或:

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

答案 1 :(得分:1)

这里没有任何可变状态(vars是不好的做法)。首先,将配置文件列表映射到(计数,配置文件)元组列表。地图似乎没必要。然后按元组中的第一项对列表进行排序,然后将其映射到配置文件列表(元组中的第二项)。

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)
}

答案 2 :(得分:0)

您还可以使用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))
}