Reputation: 25
Is there any way in scala to sort a sort of list of integers and strings without changing there relative position ? Like if I have input
List("xyz",6,4,"ghi",3,5,1,"abc")
The output should be
List("abc",1,3,"ghi",4,5,6,"xyz")
the rhe relative position of integers and strings does not change. I did this by storing the positions of digits and numbers seperately and then sorting the strings and integers in different list and putting them back together in their respective position. Is there any technique in Scala to do it faster ?
Upvotes: 1
Views: 162
Reputation: 3435
Here goes a working code. Probably not optimal, but it solves the problem:
object Test {
def removeElementFromList[T](xs:List[T], t:T):List[T] = xs match {
case h::tail if h == t => tail
case h::tail if h != t => h :: removeElementFromList(tail, t)
case Nil => Nil
}
def updateElement[T](xs:List[T], oldValue:T, newValue:T):List[T] = xs match{
case h::tail if h == oldValue => newValue :: tail
case h::tail if h != oldValue => h :: updateElement(tail, oldValue, newValue)
case Nil => Nil
}
//ascending
def sortRetainingPosition[T](xs:List[(T, Int)])(implicit cmp:Ordering[T]):List[(T, Int)] = {
xs match{
case h :: tail =>{
val minimalElement = xs.minBy(_._1)
if(h == minimalElement) h :: sortRetainingPosition(tail) else{
(minimalElement._1, h._2) :: sortRetainingPosition(updateElement(tail, minimalElement, (h._1, minimalElement._2)))
}
}
case Nil => Nil
}
}
def main(args:Array[String]):Unit = {
val input = List("xyz",6,4,"ghi",3,5,1,"abc")
val positioned = input.zipWithIndex
val strings = positioned.filter(_._1.isInstanceOf[String]).asInstanceOf[List[(String, Int)]]
val ints = positioned.filterNot(_._1.isInstanceOf[String]).asInstanceOf[List[(Int, Int)]]
val partiallySorted = sortRetainingPosition(strings) ++ sortRetainingPosition(ints)
val result = partiallySorted.sortBy(_._2).map(_._1)
println(result)
}
}
Upvotes: 1