Abhish Yozab
Abhish Yozab

Reputation: 25

Sort list of Strings and Integers inplace Scala

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

Answers (1)

Alexander Arendar
Alexander Arendar

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

Related Questions