scala 连接填充字符串

uxhixvfz  于 2023-10-18  发布在  Scala
关注(0)|答案(8)|浏览(133)

我有三个字符串,例如“A”,“B”,“C”。我必须产生的字符串的结果,从连接它们,只有第二个字符串必须填补空白,以给定的长度。
这是我的第一次尝试,由直觉和一般Scala newbiness指导:

  1. val s1 = "A"
  2. val s2 = "B"
  3. val s3 = "C"
  4. val padLength = 20
  5. val s = s1 + s2.padTo(padLength, " ") + s3

这是错误的,因为padTo返回一个SeqLike,它的toString不返回内部的字符串,而是一个类似于Vector的表示。
在Scala中,最好的习惯方法是什么?

hgtggwj0

hgtggwj01#

String可以(通过这里隐式转换为StringOps)被认为是一个 * 字符 * 的集合,所以你的填充应该是:

  1. val s = s1 + s2.padTo(padLength, ' ') + s3 // note the single quotes: a char

String上调用.padTo(padLength, " ")实际上会返回Seq[Any],因为在序列中会同时出现字符和字符串。

fcg9iug3

fcg9iug32#

你还没说你想往左还是往右。只需使用格式:

  1. val s = f"$s1%s$s2%20s$s3"

或者,在Scala 2.10之前(或者如果你需要“20”作为参数):

  1. val s = "%s%"+padLength+"s%s" format (s1, s2, s3)

使用负填充将填充空间添加到右侧而不是左侧。

qnyhuwrf

qnyhuwrf3#

有人应该提到你应该打开警告:

  1. apm@mara:~$ skala -Ywarn-infer-any
  2. Welcome to Scala version 2.11.0-20130524-174214-08a368770c (OpenJDK 64-Bit Server VM, Java 1.7.0_21).
  3. Type in expressions to have them evaluated.
  4. Type :help for more information.
  5. scala> "abc".padTo(10, "*").mkString
  6. <console>:7: warning: a type was inferred to be `Any`; this may indicate a programming error.
  7. val res0 =
  8. ^
  9. res0: String = abc*******

请注意,这样做(本身)没有错。
也许有一个用例:

  1. scala> case class Ikon(c: Char) { override def toString = c.toString }
  2. defined class Ikon
  3. scala> List(Ikon('#'),Ikon('@'),Ikon('!')).padTo(10, "*").mkString
  4. res1: String = #@!*******

或更好

  1. scala> case class Result(i: Int) { override def toString = f"$i%03d" }
  2. defined class Result
  3. scala> List(Result(23),Result(666)).padTo(10, "---").mkString
  4. res4: String = 023666------------------------

由于这不是您的用例,也许您应该询问是否希望使用冗长且充满危险的API。
所以丹尼尔的答案才是正确的。我不知道为什么他的例子中的格式字符串看起来如此可怕,但它通常看起来更温和,因为在大多数可读的字符串中,您只需要在少数地方格式化字符。

  1. scala> val a,b,c = "xyz"
  2. scala> f"$a is followed by `$b%10s` and $c%.1s remaining"
  3. res6: String = xyz is followed by ` xyz` and x remaining

需要添加虚假格式化程序的一种情况是需要换行符:

  1. scala> f"$a%s%n$b$c"
  2. res8: String =
  3. xyz
  4. xyzxyz

我认为这个函数应该处理f”$a%n$B”。哦,等等,2.11年就修好了。

  1. scala> f"$a%n$b" // old
  2. <console>:10: error: illegal conversion character
  3. f"$a%n$b"
  4. scala> f"$a%n$b" // new
  5. res9: String =
  6. xyz
  7. xyz

所以现在真的没有理由不插进去了。

展开查看全部
unguejic

unguejic4#

有一个formatted方法可用。举例来说:

  1. val s = s1 + s2.formatted("%-10s") + s3

format

  1. val s = s1 + "%-10s".format(s2) + s3

但我只会使用它,如果padLength可以直接嵌入。
如果在其他地方定义了它(如在您的示例中),您可以使用padTo,就像Ellaysama指出的那样。
如果你想“向左填充”,你可以使用一个隐式类:

  1. object Container {
  2. implicit class RichChar(c: Char) {
  3. def repeat(n: Int): String = "".padTo(n, c)
  4. }
  5. implicit class RichString(s: String) {
  6. def padRight(n: Int): String = {
  7. s + ' '.repeat(n - s.length)
  8. }
  9. def padLeft(n: Int): String = {
  10. ' '.repeat(n - s.length) + s
  11. }
  12. }
  13. }
  14. object StringFormat1Example extends App {
  15. val s = "Hello"
  16. import Container._
  17. println(s.padLeft(10))
  18. println(s.padRight(10))
  19. }
展开查看全部
0kjbasz6

0kjbasz65#

这一方法:

  1. val s = s1 + s2.padTo(padLength, " ").mkString + s3

但感觉不太稳定

slwdgvem

slwdgvem6#

这一点值得添加到Misc重新表述中:

  1. scala> val a = "A"; val b="B";val c="C"
  2. a: String = A
  3. b: String = B
  4. c: String = C
  5. scala> b.padTo(10, " ").mkString(a, "", c)
  6. res1: String = AB C

这样就能为周日的教堂节省一些钱
我开始相信在这个非常不稳定的提交中利用mkString。

sqserrrh

sqserrrh7#

  1. s1 + s2 + " "*(padLength - s2.size) + s3
oknwwptz

oknwwptz8#

我相信Scala最惯用的方法是在一个由.toString方法转换为String的单个空格Char上使用*操作符,所以它是:

  1. // for right padding
  2. val sr = s1 + s2 + ' '.toString * padLength + s3
  3. // for left padding
  4. val sl = s1 + ' '.toString * padLength + s2 + s3

相关问题