CodingNow
CodingNow

Reputation: 1028

make a list of right adjusted Strings using space as the padding character

My aim is to make a list of right adjusted Strings using space as the padding character.

The input is a List(which can be a list of numbers or a list of strings), and the output is a list of right adjusted Strings.

My implementation is like below:

def rightJustify(width: Int)(str: String): String = {
  require(str.length < w)
  List.fill(width - str.length)(' ').mkString + str
}

def makeStrs[T](lst: List[T], useValue: Boolean): List[String] = {
  if (useValue) lst.map(x => rightJustify(5)(x.toString))
  else          lst.map(_ => rightJustify(5)("")) //Just make several space characters
}

//test code
def makeListStrs: List[String] = {
  val header = List("Car", "Cat", "Dog")
  val useValue = true
  makeStrs(header, useValue) ++ // a bunch of strings
    makeStrs((1 to 5).toList, !useValue) ++ // a bunch of spaces 
    makeStrs((1 to 15).toList, useValue) ++  // a bunch of numbers
    makeStrs((1 to 5).toList, !useValue)   //a bunch of spaces
}

The code works, but I'm not sure if function makeStrs can be made more concise. Any hints are appreciated.

Upvotes: 0

Views: 284

Answers (2)

Seth Tisue
Seth Tisue

Reputation: 30453

@jwvh's solution involving optimizing both makeStrs and rightJustify considered together is very good. But let's also consider just makeStrs by itself:

Your makeStrs is already so short that in real life, I'd probably just let the repetition pass. But when more code is involved, eliminating the repetition becomes more appealing.

Here's one way to reduce the repetition:

def makeStrs[T](lst: List[T], useValue: Boolean): List[String] = {
  lst.map(x => rightJustify(5)(
    if (useValue) x.toString
    else "")

And another:

def makeStrs[T](lst: List[T], useValue: Boolean): List[String] = {
  val formatter: T => String =
    if (useValue) _.toString
    else _ => ""
  lst.map(x => rightJustify(5)(formatter(x)))
}

The second one is longer, but still worth pondering, I think. It only checks useValue once, which I like. Not so much because of concern for efficiency, but because I think doing the check once more clearly matches the structure of the problem.

I don't understand the downvotes for your question, either. Stack Overflow can be awfully hard on newcomers, sometimes.

Upvotes: 2

jwvh
jwvh

Reputation: 51271

Yes, I think more concise is possible.

def makeStrs[T](lst: List[T], useValue: Boolean): List[String] =
  if (useValue) lst.map(x => f"$x%5s")
  else          lst.map(_ => " "*5)

Upvotes: 2

Related Questions