2016-08-18 2 views
2

Für zB Etwas wie:Wie kombiniere ich mehrere NULL-fähige NSPredicates?

var finalPredicate = NSPredicate(format: "") 

    if (screen != nil) { 
     screenPredicate = NSPredicate(format: "screen = %@", screen!) 
     finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [screenPredicate!]) 
    } 

    if (feature != nil) { 
     featurePredicate = NSPredicate(format: "feature = %@", feature!) 
     finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [finalPredicate, featurePredicate!]) 
    } 

    if (shouldDisplayPredicate != nil) { 
     shouldDisplayPredicate = NSPredicate(format: "shouldDisplay = %@", shouldDisplay!) 
     finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [finalPredicate, shouldDisplayPredicate!]) 
    } 
    if (hasDisplayed != nil) { 
     displayPredicate = NSPredicate(format: "hasDisplayed = %@", hasDisplayed!) 
     finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [finalPredicate, displayPredicate!]) 
    } 

Gibt es einen besseren Weg, dies zu tun, wo die Prädikate null oder nicht sein könnten?

Dank

Antwort

1

Zunächst sollten Sie die erzwungene Abwickeln vermeiden und

if screen != nil { 
    // ... add predicate for `screen!` ... 
} 

durch eine optionale Bindung ersetzen:

if let screenValue = screen { 
    // ... add predicate for `screenValue` ... 
} 

When should I compare an optional value to nil? für einen guten Überblick über dieses Thema vergleichen. Das gleiche mehr erreicht werden kann, die kompakt map() Methode von Optional Verwendung:

screen.map { /* ... add predicate for `$0` ... } 

Die Schließung nur dann, wenn screen != nil genannt wird, und dann im Inneren $0 der Verschluss der ungeöffnete Wert.

Zweitens ist es einfacher, ein Array zuerst mit allen erforderlichen Prädikaten zu füllen und das Verbundprädikat nur einmal zu erstellen. Damit können Sie auch überprüfen, ob überhaupt ein Suchattribut gesetzt wurde.

Ihr Code wird dann

var predicates: [NSPredicate] = [] 
if let screenValue = screen { 
    predicates.append(NSPredicate(format: "screen = %@", screenValue)) 
} 
if let featureValue = feature { 
    predicates.append(NSPredicate(format: "feature = %@", featureValue)) 
} 
// ... other search attributes ... 
if !predicates.isEmpty { 
    let finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:predicates) 
} 

oder

var predicates: [NSPredicate] = [] 
screen.map { predicates.append(NSPredicate(format: "screen = %@", $0)) } 
feature.map { predicates.append(NSPredicate(format: "feature = %@", $0)) } 
// ... other search attributes ... 
if !predicates.isEmpty { 
    let finalPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:predicates) 
} 
+0

Die Karte Option ordentlich aussieht wenn auch ein wenig hart für das ungeübte (in swift) Auge zu lesen. – ofeida

+0

@ofeida: Deshalb habe ich beide vorgestellt :) –