2017-01-24 3 views
6

я увидел this post , который показал, как получить наиболее частое значение массива для скажем, целых чисел следующим образом:Как организовать массив CGPoint в порядке наиболее частых точек

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 в порядке частота и печать, скажем, кортеж со значением и количеством времени, которое оно появляется?

+1

Здесь http://codereview.stackexchange.com/questions/148763/extend-cgpoint-to-accord-to-hashable - некоторые идеи о создании CGPoint Hashable. –

+0

Если координаты не являются целыми числами, то ограниченная точность двоичных чисел с плавающей запятой может стать проблемой. Например, 'CGPoint (x: 0.1 + 0.2, y: 0)' is * different * из 'CGPoint (x: 0.3, y: 0)'. –

+1

@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 ("\ (значение) встречается \ (счет) раз") } 'https://gist.github.com/leodabus/b109b2ca9633c44974399a771690fe1d –

ответ

0

Что эта строка ошибки означает:

Type 'CGPoint' does not conform to protocol 'Hashable'

является то, что вы не можете использовать CGPoint объектов в качестве ключей словаря.

Обходной Лео Dabus упоминалось в комментариях должен хорошо работать: использовать описание отладки (String) ваших CGPoint объектов в качестве ключей словаря counts:

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") 
} 
Смежные вопросы