【问题标题】:Sorting on tuple in Scala在 Scala 中对元组进行排序
【发布时间】:2016-03-14 13:36:23
【问题描述】:

请帮我对元组多参数进行排序。

Tuple = (Option[String],Option[String],Option[String])

示例:

val lst:List[(Option[String],Option[String],Option[String])] = List(
  (Some("a"),None,None),
  (Some("b"),None,None),
  (Some("a"),Some("a"),None),
  (Some("a"),Some("b"),None),
  (Some("a"),None,Some("a")),
  (Some("a"),None,Some("b")),
  (Some("a"),None,Some("c")),
  (Some("a"),Some("a"),Some("a"))
  )
println("Sorted list = " + lst.sortBy(e=> (e._1,e._3,e._2)).mkString("\n"))

原始输出

 Sorted list= (Some(a),None,None)
  (Some(a),Some(a),None)
  (Some(a),Some(b),None)
  (Some(a),None,Some(a))
  (Some(a),Some(a),Some(a))
  (Some(a),None,Some(b))
  (Some(a),None,Some(c))
  (Some(b),None,None)

预期输出:

(Some(a),None,None)
(Some(a),Some(a),None)
(Some(a),Some(b),None)
(Some(a),None,Some(a))
(Some(a),Some(a),Some(a)) - This line should be placed at last but one position 
(Some(a),None,Some(b))    - These two lines
(Some(a),None,Some(c))    - should come above the line
(Some(b),None,None)

换句话说,元组中的第一个元素总是“Some”而不是“None”。第二个和第三个元素的值可能为“None”。

输出应按第一个元素排序,然后是第二个元素的所有“Some”值和第三个元素的所有“None”值,然后是第三个元素的所有“Some”值和第二个元素的“None”元素。之后,按第二个和第三个元素排序(两个值都是“一些”而不是“无”)。预期的输出显示了这一点。

元组中每个元素的简单排序无法按预期工作。

【问题讨论】:

  • 为什么是e._1._1?不应该只是e._1吗?
  • 你最好将你的元组重构为一个case类,并实现math.Ordering for,这样会大大提高可读性。
  • 我没有看到示例和预期输出有明显区别。您能否更清楚地说明哪一行与预期不符?
  • 不明白为什么a,None,None a,z,None a,None,b 不应该是a,None,None a,None,b a,z,None?
  • 我发现您大量使用了“get tuple”运算符 (._X),尤其是 e._1._3 不可读

标签: scala sorting tuples


【解决方案1】:

代码

“未排序”输入一点点,你可以看到它真的在排序。

val lst:List[(Option[String],Option[String],Option[String])] = List(
  (Some("a"),None,None),
  (Some("b"),None,None),
  (Some("a"),Some("b"),None),
  (Some("a"),Some("a"),None),
  (Some("a"),None,Some("c")),
  (Some("a"),None,Some("a")),
  (Some("a"),None,Some("b")),
  (Some("a"),Some("a"),Some("a"))
)

def getValue(el : (Option[String],Option[String])) = {
  el match {
    case (None, None) => 0
    case (Some(a), None) => 1
    case (None, Some(b)) => 2
    case (Some(a), Some(b)) => 3
  }
}

lst.sortBy(e => (e._1, getValue(e._2, e._3), e._2, e._3))

在第一个元组、“特殊规则”、第二个元组和第三个元组之后排序。

输出

List((Some(a),None,None), 
     (Some(a),Some(a),None), 
     (Some(a),Some(b),None), 
     (Some(a),None,Some(a)), 
     (Some(a),None,Some(b)), 
     (Some(a),None,Some(c)), 
     (Some(a),Some(a),Some(a)), 
     (Some(b),None,None))

按预期输出。

【讨论】:

  • @jony 刚刚更新了我的答案,现在它应该适合您的问题。也许它可能会更漂亮一点,但它有效,这很重要:-)
  • 简单、整洁、聪明。谢谢。
猜你喜欢
  • 1970-01-01
  • 2014-12-14
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 2011-02-07
  • 2016-08-28
相关资源
最近更新 更多