Scala - how to format a collection into a String?

samba :

I'm trying to parse Metrics data into a formatted String so that there is a header and each record below starts from a new line. Initially I wanted to get something close to a table formatting like this:

Id | Name  | Rate | Value
1L | Name1 | 1    | value_1
2L | Name2 | 2    | value_2
3L | Name3 | 3    | value_3

But my current implementation results in the following Error:

java.util.MissingFormatArgumentException: Format specifier '%-70s'

What should I change in my code to get it formatted correctly?

import spark.implicits._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._

case class BaseMetric(val id: Long,
                     val name: String,
                     val rate: String,
                     val value: String,
                     val count: Long, 
                     val isValid: Boolean
) { 

   def makeCustomMetric: String = Seq(id, name, rate, value).mkString("\t")

}

val metric1 = new BaseMetric(1L, "Name1", "1", "value_1", 10L, true)
val metric2 = new BaseMetric(2L, "Name2", "2", "value_2", 20L, false)
val metric3 = new BaseMetric(3L, "Name3", "3", "value_3", 30L, true)

val metrics = Seq(metric1, metric1, metric1)



def formatMetrics(metrics: Seq[BaseMetric]): String = {
    val pattern = "%-50s | %-70s | %-55s | %-65s | %f"

    val formattedMetrics: String = pattern.format(metrics.map(_.makeCustomMetric))
      .mkString("Id | Name | Rate | Value\n", "\n", "\nId | Name | Rate | Value")
    formattedMetrics

  }

val metricsString = formatMetrics(metrics)
Saskia :

The specific error is due to the fact that you pass a Seq[String] to format which expects Any*. You only pass one parameter instead of five. The error says it doesn't find an argument for your second format string.

You want to apply the pattern on every metric, not all the metrics on the pattern. The paddings in the format string are too big for what you want to achieve.

    val pattern = "%-2s | %-5s | %-4s | %-6s"
    metrics.map(m => pattern.format(m.makeCustomMetric: _*))
      .mkString("Id | Name  | Rate | Value\n", "\n", "\nId | Name  | Rate | Value")

The _* tells the compiler that you want to pass a list as variable length argument. makeCustomMetric should return only the List then, instead of a string.

def makeCustomMetric: String = Seq(id, name, rate, value)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324735&siteId=1