简体   繁体   English

Scala - 如何将集合格式化为字符串?

[英]Scala - how to format a collection into a String?

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.我正在尝试将 Metrics 数据解析为格式化的字符串,以便有一个 header 并且下面的每条记录都从一个新行开始。 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' java.util.MissingFormatArgumentException:格式说明符“%-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)

The specific error is due to the fact that you pass a Seq[String] to format which expects Any*.特定错误是由于您将 Seq[String] 传递给期望 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. makeCustomMetric应该只返回列表,而不是字符串。

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

Scala string interpolation is the optimized way to concat/foramt strings. Scala 字符串插值是连接/格式化字符串的优化方法。 Reference: https://docs.scala-lang.org/overviews/core/string-interpolation.html参考: https://docs.scala-lang.org/overviews/core/string-interpolation.html

s"id: $id ,name: $name ,rate: $rate ,value: $value ,count: $count, isValid: $isValid"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM