2017-01-24 12 views
6

Widziałem this post który pokazał jak się najczęstszą wartość tablicy za powiedzmy całkowitymi w następujący sposób:Jak zorganizować szereg CGPoint w kolejności najczęstszych punktów

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") 
} 

chcę aby osiągnąć ten sam wynik dla tablicy CGPoints, jest to trochę inne. Próbowałem za pomocą tego samego kodu i got błąd:

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

na linii

var counts = [CGPoint: Int]() 

i błędem

Value of type 'CGPoint' has no member '1' 

na linii

if let (value, count) = counts.max(isOrderedBefore: {$0.1 < $1.1}) { 

Jak można Układam tablicę CGPoint w kolejności częstotliwość i druk mówią, krotka z wartością i czasem, w jakim się pojawia?

+1

Tutaj http://codereview.stackexchange.com/questions/148763/extending-cgpoint-to-conform-to-hashable to kilka pomysłów na temat tworzenia CGPoint Hashable. –

+0

Jeśli współrzędne nie są liczbami całkowitymi, ograniczona może być precyzja binarnych liczb zmiennoprzecinkowych. Jako przykład, 'CGPoint (x: 0.1 + 0.2, y: 0)' jest * inny * od 'CGPoint (x: 0.3, y: 0)'. –

+1

@MartinR dlaczego nie używać po prostu debugDeCGPoint do tworzenia słownika? 'var counts = [String: Int]() myArray.forEach {counts [$ 0.debugDescription] = (liczy [$ 0.debugDescription] ?? 0) + 1} jeśli let (value, count) = counts.max (przez: {$ 0.value <$ 1.value}) { print ("\ (wartość) występuje \ (liczba) razy") } 'https://gist.github.com/leodabus/b109b2ca9633c44974399a771690fe1d –

Odpowiedz

0

Co ta linia błędu oznacza:

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

jest to, że nie można używać CGPoint przedmiotów jak klucze do słownika.

Obejście Leo Dabus wspomniano w komentarzach powinny działać dobrze: użyć opisu debugowania (String) Twoich CGPoint obiektów jako klucze do słownika 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") 
} 
Powiązane problemy