我正在尝试检查Map [Int,Long]的顺序是否正确。基本上,地图中的每个键都代表事件应该发生的顺序,并且值是时间戳记(epoch milli)。
依序映射(好:对):
Map(1 -> 1558324800000, 2 -> 1558497600000, 3 -> 1558584000000, 5 -> 1559188800000)
乱序映射(错误:错误-事件5乱序):
Map(1 -> 1558324800000, 2 -> 1558497600000, 3 -> 1558584000000, 4 -> 1559016000000, 5 -> 1558497600000)
我基本上想按键排序(只要值按升序排序,某些键可能会丢失),然后检查时间戳记值是否按升序排序。我对如何执行此检查有些困惑。
答案 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
(给出非负键的标准顺序)。