检查Map是否按值排序

时间:2019-07-12 20:18:38

标签: scala

我正在尝试检查Map [Int,Long]的顺序是否正确。基本上,地图中的每个键都代表事件应该发生的顺序,并且值是时间戳记(epoch milli)。

  • 当键== 1时,这意味着第一个事件,然后是相应的时间戳。
  • 当键== 2时,这意味着第二个事件,然后是相应的时间戳。时间戳应大于1的时间戳。
  • 当键== 3时,这意味着第三个事件,然后是相应的时间戳。时间戳应大于2的时间戳。

依序映射(好:对):

Map(1 -> 1558324800000, 2 -> 1558497600000, 3 -> 1558584000000, 5 -> 1559188800000)

乱序映射(错误:错误-事件5乱序):

Map(1 -> 1558324800000, 2 -> 1558497600000, 3 -> 1558584000000, 4 -> 1559016000000, 5 -> 1558497600000)

我基本上想按键排序(只要值按升序排序,某些键可能会丢失),然后检查时间戳记值是否按升序排序。我对如何执行此检查有些困惑。

4 个答案:

答案 0 :(得分:4)

没有理由对其进行两次排序...

m.size <= 1 ||
m.toList.sortBy(_._1).sliding(2).forall{ case List((_, a), (_, b)) => a <= b }

答案 1 :(得分:3)

这是一种方法:将Map转换为已排序的元组列表,然后执行sliding(2)来检查相邻值是否顺序正确:

val m1 = Map(1 -> 1558324800000L, 2 -> 1558497600000L, 3 -> 1558584000000L, 5 -> 1559188800000L)
val m2 = Map(1 -> 1558324800000L, 2 -> 1558497600000L, 3 -> 1558584000000L, 4 -> 1559016000000L, 5 -> 1558497600000L)

def checkKVOrdered(m: Map[Int, Long]): Boolean =
  m.toList.sortBy(_._1).map(_._2).sliding(2).forall{ case Seq(a, b) => a <= b }

checkKVOrdered(m1)
// res1: Boolean = true

checkKVOrdered(m2)
// res2: Boolean = false

答案 2 :(得分:2)

尝试

def isOrderedByValue(m: Map[Int, Long]): Boolean = {
  val l = m.toSeq.sortBy(_._1).map(_._2)
  l == l.sorted
}

或者如果听从路易斯的建议,请尝试

def isOrderedByValue(m: List[(Int, Long)]): Boolean = {
  val l = m.sortBy(_._1).map(_._2)
  l == l.sorted
}

尽管如此,该解决方案仍进行了两次排序,而其他答案未必如此。

答案 3 :(得分:2)

注意:如果构造SortedMap[Int, Long]而不是Map[Int, Long],则会免费获得键顺序的迭代(权衡是每次插入都将花费更长的时间)。在这种情况下,

val map: SortedMap[Int, Long] = ...
val isOrdered = map.size <= 1 || map.sliding(2).forall { m => m.head._2 <= m.last._2 }

应该工作。另请参见IntMap(给出非负键的标准顺序)。