我最近才开始与Scala合作,但遇到了一个我似乎找不到解决方案的问题。因此,基本上,我得到了一个名为“ in.txt”的输入文本文件,其中包括我必须像下面显示的那样使用的坐标行。
2 1
6 6
4 2
2 5
2 6
2 7
3 4
6 1
6 2
2 3
6 3
6 4
6 5
6 7
我决定使用列表存储所有值,以便以后可以使用内置函数对这些值进行计算。
val lines = io.Source.fromFile("in.txt").getLines
val coordinates =
lines
.drop(0)
.toList
.sortWith(_<_)
.mkString
.replaceAll("\\s", "")
.grouped(2)
.toList
一切正常,因为 println(coordinates)的输出为
List(21, 23, 25, 26, 27, 34, 42, 61, 62, 63, 64, 65, 66, 67)
但是我接下来要做的是从这个列表中创建多个列表。例如,如果一个值以“ 2”开头,并且所有以“ 2”开头的值都将被放置在新列表中,则应创建一个新列表,如下所示:
List(21, 23, 25, 26, 27)
然后将相同的操作用“ 3”,然后是“ 4”,依此类推。
使用诸如 .partition 和 .groupBy 之类的函数有效,但要考虑到以下事实:坐标中的值也可以达到4位数字,并且它们如果输入文件被编辑,则可以更改,手动编写所有这些条件会很麻烦。因此,基本上我的问题是:是否可以通过使用Scala的功能以及某种形式的迭代来实现这一目标?
谢谢!
答案 0 :(得分:0)
我假设您的文件可以混合使用2、3、4,...个数字字符串。
scala> val l = List("12", "13", "123", "1234")
l: List[String] = List(12, 13, 123, 1234)
scala> val grouped = l.groupBy(s => s.take(s.length - 1)).values
grouped: Iterable[List[String]] = MapLike(List(123), List(12, 13), List(1234))
如果要对此排序:
val grouped = l.groupBy(s => s.take(s.length - 1)).toSeq.sortBy(_._1).map{ case (_, l) => l.sorted}
grouped: Seq[List[String]] = ArrayBuffer(List(12, 13), List(123), List(1234))
答案 1 :(得分:0)
您可以生成具有一定范围的所有输入条件:
val conditions = 1 to 9999
然后将它们折叠起来,按其每个元素过滤原始列表:
conditions.foldLeft(List():List[List[Int]])((acc, elem) => l.filter(_.toString.startsWith(elem.toString))::acc).filterNot(_.isEmpty)
输出
res28: List[List[Int]] = List(List(67), List(66), List(65), List(64), List(63), List(62), List(61), List(42), List(34), List(27), List(26), List(25), List(23), List(21), List(61, 62, 63, 64, 65, 66, 67), List(42), List(34), List(21, 23, 25, 26, 27))