2016-07-09 27 views
1

Ich habe ein [NSManagedObject], das ich basierend auf einer am nächsten passenden Zeichenfolge sortieren möchte."[NSManagedObject]" sortiert nach übereinstimmender Zeichenfolge

Ich habe mit sortInPlace untersucht, aber es sieht so aus, als würde es nur Werte vergleichen und sortieren.

Ich habe auch untersucht, mit einem Prädikat, aber ich kann nicht scheinen, Prädikate auf [NSManagedObject] zu verwenden.

Ich versuche dies:

if let query = searchController.searchBar.text { 
     let predicate = NSPredicate(format: "title contains[c] %@", query) 
     self.objects.//using predicate here doesn't work 


    } 

Irgendwelche Ideen, was ich tun muss ??

+0

'NSPredicate' wird nicht zum Sortieren verwendet. Sie benötigen einen 'NSSortDescriptor' und Sie müssen den Algorithmus für die engste übereinstimmende Auswertung erstellen. – Sulthan

Antwort

1

Wie @Sulthan erwähnt, werden NSManagedObjects normalerweise mit einem NSSortDescriptor sortiert, der nur eine alphabetische Sortierung bei Verwendung mit NSFetchRequest bereitstellt.

Es gibt andere Möglichkeiten, die Ergebnisse nach Zeichenketten-Nähe zu sortieren. In der Regel erfolgt dies mithilfe eines vordefinierten Index, wobei jedes NSManagedObject ein Knoten in einer Struktur oder einem Diagramm ist. Die Implementierung eines solchen Index ist nicht übermäßig komplex, erfordert jedoch einige Hintergrundkenntnisse.

Wenn Ihr Datensatz nicht zu groß ist, können Sie die Objekte möglicherweise als Array sortieren, wie Sie in Ihrem Code gezeigt haben. Ein Schlüsselelement beim Sortieren ist hier das Definieren der Regeln zum Bestimmen, wie nahe eine Kandidaten-Zeichenfolge mit der Abfrage übereinstimmt.

Eine Möglichkeit, dies zu tun, ist die Levenshtein-Distanz, um Übereinstimmungen zu berechnen. Andere Arten der Übereinstimmung könnten ebenfalls funktionieren, wie zum Beispiel das Messen der längsten übereinstimmenden Teilkette.

  1. Berechnen Sie den Levenshtein Abstand zwischen der Abfrage und jedem der Kandidaten. Die Levenshtein-Distanz ist grob gesagt ein Maß dafür, wie unterschiedlich eine Saite von einer anderen ist. Ein Abstand von 0 bedeutet, dass die Strings identisch sind. Je größer der Abstand, desto unterschiedlicher sind die Saiten.
  2. Kandidaten filtern, bei denen der Levenshtein-Abstand der gleiche wie die Wortlänge ist (dh die Wörter teilen keine Ähnlichkeiten)
  3. Bestellen Sie die Ergebnisse von der Levenshtein-Entfernung.

Hier ist ein Beispiel dafür, wie diese auf einem Array von Strings funktionieren könnte:

let data = ["shore", "show", "sheep", "shop", "ship", "shape", "cape", "cope", "cap", "apple", "nape"] 

let query = "ape" 

// Calculate how closely each item matches the query. 
// This creates an array of tuples of the form (word, distance). 
let proximity = data.map() { 
    return ($0, levenshtein($0, bStr: query)) 
} 

// Remove items which are completely different. 
let filtered = proximity.filter() { 
    return $0.1 < $0.0.characters.count 
} 

// Order items by proximity to the query. 
// This places close matches at the top. 
let sorted = filtered.sort() { 
    return $0.1 < $1.1 
} 

// Filter tuples to return the data. 
let result = sorted.map() { 
    return $0.0 
} 

print(result) 

ich dieses Beispiel mit einem Levenshtein implementation on GitHub getestet. Es sollte möglich sein, dies einfach zu übertragen, um ein Array von NSManagedObjects zu sortieren.

+0

'NSSortDescriptor' ist definitiv nicht auf die alphabetische Sortierung beschränkt. Sie können es verwenden, um basierend auf jedem Vergleich zu sortieren, für den Sie Code schreiben können. –

+0

@TomHarrington Sie haben Recht im allgemeinen Fall, obwohl ich mich auf die Verwendung von NSSortDescriptor mit einem NSFetchRequest bezog, von dem ich annahm, dass der Fragesteller daran interessiert war, da die Frage von NSManagedObjects handelt (die Antwort wurde klargestellt, um dies zu verdeutlichen). AFAIK Sie können keinen beliebigen Code mit Sortierungsdeskriptor in einem NSFetchRequest verwenden, der es auf den Standardzeichenfolgenkomparator beschränkt. Bitte korrigieren Sie mich, wenn ich hier falsch liege. –

+0

Dachte nicht, Sortierung könnte so kompliziert werden. Werde mich damit beschäftigen und Feedback geben, wenn ich es getan habe – Starlord