Kevin
Kevin

Reputation: 7946

How do you pad a string in Scala with a character for missing elements in a Vector?

If I have a sparse list of numbers:

Vector(1,3,7,8,9)

and I need to generate a string of a fixed size which replaces the 'missing' numbers with a given character that might look like this:

1.3...789

How would I do this in Scala?

Upvotes: 1

Views: 579

Answers (3)

integer-j
integer-j

Reputation: 344

Well, I'm not sure the range of the integers. So I'm assuming that they may not fit into a char and used a string. Try this:

val v = Vector(1,3,7,8,9)
val fixedStr = ( v.head to v.last )
                   .map( i => if (v.contains(i)) i.toString else "." )
                   .mkString

If you are only dealing with single digits then you may change the strings to chars in the above.

-- edit --

ok, so I couldn't help myself and addressed the issue of sparse vector and wanted to change it to use the sliding function. Figured it does no good sitting on my PC so sharing here:

v.sliding(2)
  .map( (seq) => if (seq.size == 2) seq else seq ++ seq )  //normalize window to size 2
  .foldLeft( new StringBuilder )( (sb, seq) =>             //fold into stringbuilder
    seq match { case Seq(a,b) => sb.append(a).append( "." * (b - a - 1) ) } )
  .append( v.last )
  .toString

Upvotes: 4

marios
marios

Reputation: 8996

One way to do this is using sliding and pattern matching:

def mkNiceString(v: Vector[Int]) = {
   v.sliding(2).map{
     case Seq(a) => ""
     case Seq(a,b) => 
       val gap = b-a; 
       a.toString + (if(gap>1) "." * (gap-1) else "")
   }.mkString + v.last
}

In the REPL:

scala> mkNiceString(Vector(1,3,7,8,9,11))
res22: String = 1.3...789.11

Upvotes: 2

Peter Neyens
Peter Neyens

Reputation: 9820

If the vector is sparse, this will be more efficient than checking the range between the first and the last number.

def padVector(numbers: Vector[Int], placeHolder: String) = {
  def inner(nums: Vector[Int], prevNumber: Int, acc: String) : String = 
    if (nums.length == 0) acc
    else (nums.head - prevNumber) match {
      // the difference is 1 -> no gap between this and previous number
      case 1 => inner(nums.tail, nums.head, acc + nums.head)
      // gap between numbers -> add placeholder x times
      case x => inner(nums.tail, nums.head, acc + (placeHolder * (x-1)) + nums.head)
    }

  if (numbers.length == 0) ""
  else inner(numbers.tail, numbers.head, numbers.head.toString)
}

Output:

scala> padVector(Vector(1,3,7,8,9), ".")
res4: String = 1.3...789

Upvotes: 1

Related Questions