如何在4列上实现排序逻辑升序

时间:2018-08-03 10:44:06

标签: scala sorting

我尝试使用以下逻辑对文件进行排序,但是我需要对文件进行四列排序。谁能告诉我实现4列排序的文本文件排序方法。

indata.sortBy(x => (x.split("|")(1).toInt, -x.split("|")(4).toInt).map(p => println(p)))

2 个答案:

答案 0 :(得分:0)

最简单的选择是将数据分为几列,然后按每一列依次排序:

val cols = indata.map(_.split(raw"\|").toList)

cols.sortBy(_(3)).sortBy(_(2)).sortBy(_(1)).sortBy(_(0))

在排序之前对数据进行拆分使您可以验证数据是否有效并在必要时对其进行修复,并且比在排序期间拆分数据更有效。

您可以编写与sortWith一起使用的排序函数,但这更复杂,并且更简单的解决方案通常会更好。

答案 1 :(得分:0)

假设您将源数据保存在文本文件中,则可以将拆分列按特定顺序放置在tuple中的函数传递给方法sortBy(这样,您只需要对列出一次遍历):

// /path/to/infile
2|101|23|2
1|103|23|3
2|102|22|1
3|101|21|2
1|103|23|1

import scala.io.Source

val indata = Source.fromFile("/path/to/infile").
  getLines.toList
// indata: List[String] = List(2|101|23|2, 1|103|23|3, 2|102|22|1, 3|101|21|2, 1|103|23|1)

val outdata = indata.
  map( _.split("\\|").map(_.toInt) ).
  sortBy(r => (r(0), -r(1), r(2), r(3))).  // Ordering: (asc, desc, asc, asc)
  map(_.mkString("|"))
// outdata: List[String] = List(1|103|23|1, 1|103|23|3, 2|102|22|1, 2|101|23|2, 3|101|21|2)

请注意,要排序的列是数字(根据您的示例代码得出的假设),因此示例中的negative r(1)以降序排列。

要将排序后的列表写回到文件中,只需使用PrintWriter

import java.io.File
import java.io.PrintWriter

val writer = new PrintWriter(new File("/path/to/outfile"))

outdata.foreach(line => writer.write(line + "\n"))
writer.close

[更新]

如果Int / String列和升序/降序混合使用,则需要为要按降序排序的列指定Ordering[T].reverse。另外,您还需要按照升/降开关将列分解以多次执行sortBy。例如:

// /path/to/infile
2|"a"|101|23
1|"c"|103|23
2|"b"|102|22
3|"a"|101|21
1|"c"|103|23

val dscStrOrder = scala.math.Ordering[String].reverse

val outdata = indata.
  map( _.split("\\|") ).
  sortBy(r => (r(2).toInt, r(3).toInt)).
  sortBy(r => r(1))(dscStrOrder).
  sortBy(r => r(0).toInt).        // Ordering: (asc, desc, asc, asc)
  map(_.mkString("|"))
// outdata: List[String] = List(1|"c"|103|23, 1|"c"|103|23, 2|"b"|102|22, 2|"a"|101|23, 3|"a"|101|21)