Reputation: 1028
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
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
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