【问题标题】:Move characters to the end of a string in scala在scala中将字符移动到字符串的末尾
【发布时间】:2020-11-22 22:59:58
【问题描述】:

我有一个包含以下类型字符串的文件:

1 2 a 3 4
5 b 6 c 7

我想将所有字母移动到字符串的末尾,所以输出将是:

1 2 3 4 a
5 6 7 b c

我试过这样:

line.replaceAll("\\D+", "") + line.replaceAll("\\d+", "")

但它给出的输出为:

1234    a
567   b c

我想保留空白并在任意行数的末尾获得所有字母的输出。

PS:我正在为 spark-scala 编写代码,所以请告诉我一个 scala 方式

【问题讨论】:

    标签: string scala


    【解决方案1】:

    假设你有file.txt,内容如下:

    1 2 a 3 4
    5 b 6 c 7
    10 b c 11 12
    

    您可以使用mapsplittoListsortedmkString 来实现您想要的结果:

    import java.io.File
    import java.io.PrintWriter
    import scala.io.Source
    
    object Main {
      def main(args: Array[String]): Unit = {
        val f = new File("file.txt")
        val temp = new File("file.tmp")
        val w = new PrintWriter(temp)
        Source
          .fromFile(f)
          .getLines
          .map { x =>
            x
              .split(' ')
              .toList
              .sorted
              .mkString(" ")
          }
          .foreach(x => w.println(x))
        w.close()
        temp.renameTo(f)
      }
    }
    

    file.txt上面运行后:

    1 2 3 4 a
    5 6 7 b c
    10 11 12 b c
    

    【讨论】:

    • 感谢@Shash 工作得很好...我正在阅读rdd 中的文件,并且rdd 映射得很好...再次感谢...简单而优雅...荣誉
    • 没问题,我去年实习的时候用过scala真的很好玩!
    • .split(" ").split(' ')(注意单引号) - 在 sorted 之前也不需要 .toList,因为 Array 也可以排序。
    • 我使用了toList,因为我看到“如果您想对数组进行排序,请参阅我的其他常见问题解答关于如何在 Scala 中对数组进行排序。”在食谱网站上:alvinalexander.com/scala/…。基本上我认为他的意思是不要在 Array 上使用.sorted
    • @ShashSinha 哦,看来我错了,采用Charsplit 版本不是Java String 的一部分,而是 Scala 之一,最后调用使用 regex 的相同方法,因此它应该是相同的。来源:github.com/scala/scala/blob/v2.13.4/src/library/scala/…
    【解决方案2】:

    您可以利用 ASCII table 中的字符按其顺序排序的优势。

    def sortStringWithSpaces(str: String): String =
      str.split(' ').sorted.mkString(" ")
    

    你可以这样使用:

    sortStringWithSpaces("1 2 a 3 4")
    // res: String = "1 2 3 4 a"
    
    sortStringWithSpaces("5 b 6 c 7")
    // res: String = "5 6 7 b c"
    
    sortStringWithSpaces("10 b c 11 12")
    // res: String = "10 11 12 b c"
    

    可以看到运行here的代码。

    【讨论】:

    • 感谢Luis 如此轻松地回答......这工作得很好,但是当我尝试超过 9 的数字时它失败...... sortStringWithSpaces("10 b c 11 12") 给出:0 1 1 1 1 2 b c
    • 感谢 @Luis 再次回复...已经接受了 Shash 的回答,但您离不转换为 List 还差一步...请记住这一点.....顺便说一句 @987654325 @ answer 完全没问题...寻找 Java 的人可以从他的回答中受益。
    【解决方案3】:

    您当前方法的主要问题是第二次替换还需要删除空格,否则它只会删除数字,但会留下字母和空格。然后,您需要一个额外的步骤来重新引入每个字符之间的原始空格。假设您想使用 Java 风格的方法,您可以尝试:

    // Java version.
    String line = "5 b 6 c 7";
    String output = line.replaceAll("\\D+", "") +
                    line.replaceAll("[\\d\\s]+", "");
    output = output.replaceAll("(?=.)", " ");
    System.out.println(output);
    
    // Scala version.
    val line = "5 b 6 c 7"
    var output = line.replaceAll("\\D+", "") +
                 line.replaceAll("[\\d\\s]+", "")
    output = output.replaceAll("(?=.)", " ")
    println(output)
    

    两个打印件:

    5 6 7 b c
    

    【讨论】:

    • 谢谢@Tim。它对 Java 和 Scala 都非常有帮助.. 但是当我输入 "10 b c 11 12" 行时,与Luis 的问题相同,输出为:1 0 1 1 1 2 b c
    • Tim 请您解释一下 output.replaceAll("(?=.)", " ") 中的正则表达式 ....我是新手正则表达式...谢谢
    • @HasnainMotagamwala 对于您更新的要求(不是您最初要求的),您必须进行排序以将数字与字母分开。我不知道如何在 Scala 中做到这一点(但 Luis 可能知道)。
    【解决方案4】:

    我知道我来晚了,但你可以做的另一件事是:

    def sortStringWhitspaces(str: String): String = {
      val partitioned = str.split(' ').partition(x => Try(x.toInt).isSuccess)
      (partitioned._1 ++ partitioned._2).mkString(" ")
    }
    

    这种方法的优点是您不需要对数字和字母进行排序。首先,您没有在问题中指定是否需要保留原始顺序,但排序并没有这样做。第二件事,排序可能会影响效率,而这个解决方案是O(n)

    代码在Scastie 运行。

    【讨论】:

    • 智能、简约、优雅。他最初的问题意味着保留订单。
    • 谢谢,正如我在回答中所说,这是模棱两可的。它可以是顺序保留的,也可以是排序的。所有示例都已排序,因此很难分辨。
    • 谢谢@Tomer。只是一个后续问题:如何知道一个方法在早期版本的 scala 中是否可用,比如如果我们必须检查 partition 在 2.11 和 2.12 中是否可用,我们如何才能找到它,比如这个方法是从哪个版本包含在 scala 中的
    • @HasnainMotagamwala 它在早期的 scala 版本中可用。您可以尝试一下,也可以搜索文档。
    猜你喜欢
    • 2021-10-04
    • 2018-02-25
    • 2013-08-25
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多