首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala中的函数重写:具有最大宽度的字符串行

Scala中的函数重写:具有最大宽度的字符串行
EN

Code Review用户
提问于 2014-01-17 14:37:15
回答 1查看 441关注 0票数 2

前几天我遇到了一个问题,我实在想不出一个功能性的解决方案。所以我放弃了我的必要的编程技巧。由于我还没有找到一个实用的解决方案,我想我应该在这里大喊救命。

用例

我有一个任意长度的字符串列表。这些字符串需要组合成具有相同最大长度的行。

当单个字符串的长度大于最大长度时,该字符串只得到它自己的行,因为每一行最终都由一个函数处理,该函数确保将所有字符串截断到适当的长度。

示例用法

代码语言:javascript
复制
scala> val rows = combineStrings(List("Short", "This is a particularly long String...", "More", "Small", "Strings"), 35)

电流输出

代码语言:javascript
复制
scala> rows.foreach(println)
Short
This is a particularly long String...
More, Small, Strings

期望输出

代码语言:javascript
复制
scala> rows.foreach(println)
Short, More, Small, Strings
This is a particularly long String...

电流溶液

代码语言:javascript
复制
def combineStrings(strs: List[String], maxLen: Int)
: List[String] = {
  import scala.collection.mutable.ListBuffer

  var scratch = strs.mkString("|")
  val rows = ListBuffer[String]()

  while (scratch.length > 1) {
    scratch.indexOf("|") match {
      case idx if (idx == -1 || scratch.length < maxLen) =>
        rows += scratch
        scratch = ""

      case idx if idx > maxLen =>
        rows += scratch.substring(0, idx)
        scratch = scratch.substring(idx+1)

      case idx =>
        val lIdx = scratch.lastIndexOf("|", maxLen)
        rows += scratch.substring(0, lIdx)
        scratch = scratch.substring(lIdx+1)
    }
  }

  rows.toList.map(_.replaceAll("\\|", ", "))
}

Notes

  • 之所以使用管道,是因为原始字符串比它们自己的管道更有可能有自己的逗号。也许其他解决方案不需要这种黑客行为。
  • 字符串保持相同的顺序,但最终我更希望有尽可能“紧凑”的行。

摘要

任何想法,如何使这更多的功能,将不胜感激。我在Scala的"String“中发现了一些看起来很有前途的函数,但我不太确定如何将它们与长度需求集成起来。

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-01-21 02:30:51

这比我第一次尝试要“实用”得多:

代码语言:javascript
复制
  def combineStrings(strs: List[String], maxLen: Int)
  : List[String] = {
    import scala.collection.mutable.StringBuilder

    strs.map(_.trim).filter(_.nonEmpty)
      .aggregate(List[StringBuilder]())({ (lbs, s) =>
        s.length match {
          case l if (l > maxLen) =>
            new StringBuilder(s) :: lbs
          case l =>
            lbs.find(_.length <= maxLen - (l+2))
              .map { sb => sb ++= s", $s"; lbs }
              .getOrElse(new StringBuilder(s) :: lbs)
        }
      }, _ ++ _
    ).map(_.toString).reverse
  }

不知道为什么我第一次不这么做。该解决方案甚至提供了所需的输出,并在长度计算中考虑了",“分隔符。

代码语言:javascript
复制
scala> val rows = combineStrings(List("Short", "This is a particularly long String...", "More", "Small", "Strings"), 35)
rows: List[String] = List(Short, More, Small, Strings, This is a particularly long String...)

scala> rows.foreach(println)
Short, More, Small, Strings
This is a particularly long String...
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/39477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档