Scala How do you sort a map that has a String, with numbers in it

こ雲淡風輕ζ 提交于 2020-06-28 03:55:34

问题


I am trying to sort a mutable.Map[String, String] by getting the string and sorting with the numbers inside the string. Input:

"Liz", "Game: 2"
"Philip", "Game: 5"
"John", "Game: 0 | Score: 9"
"Kevin", "Game: None"

Output to something like this

"John", "Game: 5 | Score: 9"
"Liz", "Game: 2"
"Philip", "Game: 0"
"Kevin", "Game: None"

I have tried this https://alvinalexander.com/scala/how-to-sort-map-in-scala-key-value-sortby-sortwith/ but it doesn't does what I want it to sort Excuse my bad grammar


回答1:


The Scala standard library knows how to sort tuples of the same type profile as long as all the internal elements can be sorted.

It also knows how to sort Options as long as the option element can be sorted.

Int values can be sorted.

So you can sort your String by internal Int values that might, or might not, be there by stuffing them in a tuple of Option[Int] elements.

import scala.util.Try

val games =
  scala.collection.mutable.Map("Liz" -> "Game: 2"
                              ,"John" -> "Game: 0 | Score: 9"
                              ,"Philip" -> "Game: 5"
                              ,"Kevin" -> "Game: None")
games.put("Jo", "Game: 11 | Score 0")

val nums = "(\\d+)?(?:\\D+(\\d+))?".r.unanchored

games.toList.sortBy{
  case (_,nums(a,b)) => (Try(a.toInt).toOption
                        ,Try(b.toInt).toOption)
}.reverse
//res1: List[(String, String)] = List((Jo,Game: 11 | Score 0)
//                                  , (Philip,Game: 5)
//                                  , (Liz,Game: 2)
//                                  , (John,Game: 0 | Score: 9)
//                                  , (Kevin,Game: None))



回答2:


You need to get the number from you string and convert it to Integer, for example:

val map: Map[String, String] = Map(("Liz", "Game: 11"), ("Philip", "Game: 5"))
val order: ((String, String)) => Integer = { case (_ , p2) => p2.stripPrefix("Game: ").toInt }
map.toSeq
  .sortWith(order(_) > order(_))
  .toList



回答3:


Sample Data:

scala> tmp
res19: scala.collection.mutable.Map[String,String] = Map(Philip -> Game: 0, John -> Game: 5, Liz -> Game: 2)

Create a case class:

case class someclass(name:String,score:Int,keyword:String)

Put the data into a List[someClass]:

val listOfScores = tmp.map(each => { 
  val name = each._1
  val keyword = each._2.split(":")(0)
  val score = each._2.split(":")(1).stripPrefix(" ").toInt
  someclass(name,score,keyword)
})

Finally sort and get the final list:

scala> listOfScores.toList.sortBy(_.score).reverse
res31: List[someclass] = List(someclass(A1,9,Goals), someclass(a2,5,Game), someclass(Liz,2,Game), someclass(John,0,Score), someclass(Philip,0,Game))


来源:https://stackoverflow.com/questions/62353779/scala-how-do-you-sort-a-map-that-has-a-string-with-numbers-in-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!