【发布时间】:2017-06-09 07:35:26
【问题描述】:
我看到this post 它展示了如何通过以下方式获取数组的最常见值,例如整数:
let myArray = [4, 4, 4, 3, 3, 3, 4, 6, 6, 5, 5, 2]
// Create dictionary to map value to count
var counts = [Int: Int]()
// Count the values with using forEach
myArray.forEach { counts[$0] = (counts[$0] ?? 0) + 1 }
// Find the most frequent value and its count with max(isOrderedBefore:)
if let (value, count) = counts.max(isOrderedBefore: {$0.1 < $1.1}) {
print("\(value) occurs \(count) times")
}
我想为CGPoints 的数组实现相同的结果,这有点不同。我尝试使用相同的代码并收到错误:
Type 'CGPoint' does not conform to protocol 'Hashable'
在线上
var counts = [CGPoint: Int]()
还有一个错误
Value of type 'CGPoint' has no member '1'
排队
if let (value, count) = counts.max(isOrderedBefore: {$0.1 < $1.1}) {
如何按频率顺序排列 CGPoint 数组并打印一个包含值和出现次数的元组?
【问题讨论】:
-
这里 codereview.stackexchange.com/questions/148763/… 是一些关于使 CGPoint Hashable 的想法。
-
如果坐标不是整数,那么二进制浮点数的有限精度可能会成为问题。例如,
CGPoint(x: 0.1 + 0.2, y: 0)与CGPoint(x: 0.3, y: 0)不同。 -
@MartinR 为什么不直接使用 CGPoint debugDescription 来创建字典呢?
var counts = [String: Int]() myArray.forEach { counts[$0.debugDescription] = (counts[$0.debugDescription] ?? 0) + 1 } if let (value, count) = counts.max(by: {$0.value < $1.value}) { print("\(value) occurs \(count) times") }gist.github.com/leodabus/b109b2ca9633c44974399a771690fe1d -
@LeoDabus:是的,您可以这样做,但是您依赖于未记录的 debugDescription 格式。此外,计算字符串哈希值(据我所知)相对“昂贵”,使用从 x/y 坐标计算的哈希值应该更快。
-
@MartinR 谢谢
标签: arrays sorting swift3 mapping