2012-04-25 12 views
30
में स्थिति

वापस फिर से मेरी NSPredicates :(निर्माण करने में अधिक सहायता की आवश्यकता होगी,का मेल 'और' और 'या' NSPredicate

Category 
{ 
    name:string 
    subs<-->>SubCategory 
} 

SubCategory 
{ 
    name:string 
    numbervalue:NSNumber 
} 

मैं जानना चाहता और और या के साथ एक विधेय बनाने का तरीका चाहते हैं ।

उदाहरण के लिए, मैं नाम == "CATEGORY_NAME" भी "valueA" या "VALUE अरब" का एक numbervalue साथ एक उपश्रेणी है कि के साथ हर श्रेणी वापसी करना चाहते हैं।

मैंने अनुमानित रचनाकारों के हर संभावित संयोजन की कोशिश की है जिसके साथ मैं आ सकता हूं लेकिन मैं इसे काम पर नहीं ला सकता हूं।

यह अब तक का सबसे अच्छा प्रयास है।

NSPredicate *predicate=[NSPredicate [email protected]"(name== %@) AND (ANY subs.numbervalue==%@ OR ANY subs.numbervalue==%@)", @"aname", value1, value2]; 

संपादित करें 1

दूसरा प्रयास। 'Numbervalue' पर फ़िल्टरिंग अभी भी काम नहीं कर रहा है।

NSNumber valueA=[NSNumber numberWithInt:20]; 
NSNumber valueA=[NSNumber numberWithInt:90]; 
NSArray *arr=[NSArray arrayWithObject:valueA,valueB,nil]; 

predicate=[NSPredicate predicateWithFormat:@"(name==%@)AND(ANY subs.numbervalue IN %@)",@"aname",arr]; 

संपादित 2

मैं सिर्फ numberValue से छानने की कोशिश की है और नाम को छोड़ दिया है alltogether।

1) इस सेट का उपयोग पूरे सेट में किया जा रहा है भले ही सेट में केवल 1 आइटम का मूल्य हो।

predicate=[NSPredicate predicateWithFormat:@"(ANY subs.numbervalue IN %@)",arr]; 

2) इस परिणाम का उपयोग उसी समस्या में करते हुए, सेट में मौजूद प्रत्येक आइटम को वापस लौटाया जाता है, भले ही उनमें से केवल 1 मेल खाता हो।

predicate=[NSPredicate predicateWithFormat:@"((SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@)[email protected] > 0)", value1, value2]; 

एक ही समस्या में सबसे सरल संस्करण परिणामों का भी उपयोग करना .... मैंने पहले यह नोटिस नहीं किया था।

NSPredicate *predicate=[NSPredicate [email protected]"(ANY subs.numbervalue==%@ ,valueA]; 

तो मुझे लगता है कि मेरी समस्या कम हो गई है।

श्रेणी एक इकाई है। उपश्रेणी एक संस्था है।

श्रेणी उपश्रेणी के साथ कई रिश्तों में से एक है और इसे उपश्रेणी के एनएसएससेट के रूप में दर्शाया गया है।

प्रत्येक उपश्रेणी में numbervalue नामक एक विशेषता है।

संपादित 3

2 categorys है परीक्षण करने के लिए। दोनों श्रेणियों में 10 subs हैं, प्रत्येक 1 -10 के numbervalue के साथ;

इस कोड का उपयोग करके दोनों श्रेणियों को प्रत्येक के लिए सभी 10 subs के साथ वापस कर दिया जाता है।

अपेक्षित परिणाम दोनों श्रेणियां लौटा दी गई हैं, प्रत्येक में केवल 2 सब के साथ।

मैं अपने सभी वस्तुओं को बाहर का पता लगाया है और डेटा सही है। समस्या यह है कि मैं एक श्रेणी को वापस नहीं कर सकता जिसने फ़िल्टर किया है।

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSManagedObjectContext *context=[[DataSource sharedDataSource]managedObjectContext]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context]; 
[fetchRequest setEntity:entity]; 

[fetchRequest setFetchBatchSize:20]; 

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; 

NSPredicate *predicate; 
NSNumber *a=[NSNumber numberWithFloat:1]; 
NSNumber *b=[NSNumber numberWithFloat:2]; 
predicate=[NSPredicate predicateWithFormat:@"(SUBQUERY(subs,$x,$x.numbervalue==%@ or $x.numbervalue==%@)[email protected]> 0)",a,b]; 

[fetchRequest setPredicate:predicate]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 

NSError *error = nil; 
[NSFetchedResultsContoller deleteCacheWithName:nil]; 

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"name" cacheName:@"Master"]; 
aFetchedResultsController.delegate = self; 

self.fetchedResultsController = aFetchedResultsController; 

if (![self.fetchedResultsController performFetch:&error]) { 

    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 
+0

आप 'NSCompoundPredicate' जाँच की है? यह आपकी मदद करनी चाहिए। 0 ... और (कोई भी subs.numberValue IN% @) का उपयोग करने का प्रयास करें, "@ fooName", numArray' – Eimantas

+0

युक्तियों के लिए धन्यवाद – dubbeat

+0

$ x.numbervalue का उपयोग करें और $ numbervalue का उपयोग करें। फिर कैश को शून्य पर सेट करने का प्रयास करें पहले और परिणाम देखें। –

उत्तर

32

मैं SUBQUERY का उपयोग करके निम्नलिखित कार्य करूंगा।

[NSPredicate [email protected]"(name == %@) AND (SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@)[email protected] > 0)", @"aname", value1, value2]; 

इसे आज़माएं और मुझे बताएं।

एक अन्य समाधान पूरे संग्रह subs हड़पने के लिए और फिर फ़िल्टर कर तत्वों value1 या value2 मेल की जांच करने के विधेय के साथ सेट पुनः प्राप्त किया जा सकता है।

उम्मीद है कि यह मदद करता है।

संपादित

आप Eimantas सुझाव यकीन करने के लिए कर सही सरणी बनाने के लिए का पालन करें:

NSNumber valueA = [NSNumber numberWithInt:20]; 
NSNumber valueB = [NSNumber numberWithInt:90]; 
NSArray *arr = [NSArray arrayWithObjects:valueA, valueB, nil]; 
+0

क्या हो रहा है यह है कि यदि subs के संग्रह में उदाहरण के लिए 9 0 का मूल्य है, तो शेष 0 कह रहे हैं, सबस का पूरा संग्रह अभी भी – dubbeat

+0

उपयोग करने का प्रयास करें केवल * (सबक्वायरी (सब, $ x, $ x.numbervalue ==% @ या $ x.numbervalue ==% @)। @ count> 0) * predicate में और सरणी को अतिरिक्त अनुमान के साथ फ़िल्टर करने के लिए फ़िल्टर करें नाम। –

+0

केवल सब्सक्राइब का उपयोग करके आप क्या परिणाम प्राप्त करते हैं? –

1

एक अन्य विकल्प एक NSCompoundPredicate (नोट andPredicateWithSubpredicates उपयोग करने के लिए है करता है एक और लेकिन देखते हैं उपयोग करने के लिए कुछ विकल्प, यह 2 खोज करने से कहीं अधिक कुशल होना चाहिए)

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCompoundPredicate_Class/index.html#//apple_ref/occ/clm/NSCompoundPredicate/andPredicateWithSubpredicates :)

49

@ स्टुअर्ट के उत्तर में जोड़ें, आप अपने OR& और इस तरह के संचालन के लिए एनएससीओम्पाउंड क्रेडिट का उपयोग कर सकते हैं।

Obj सी - या

// OR Condition // 

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"]; 
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"]; 
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]]; 

Obj सी - और

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"]; 
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"]; 
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]]; 

स्विफ्ट - या

let predicate1:NSPredicate = NSPredicate(format: "X == 1") 
let predicate2:NSPredicate = NSPredicate(format: "Y == 2") 
let predicate:NSPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2]) 

स्विफ्ट - और

let predicate1:NSPredicate = NSPredicate(format: "X == 1") 
let predicate2:NSPredicate = NSPredicate(format: "Y == 2") 
let predicate:NSPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2]) 

स्विफ्ट 3 - या

let predicate1 = NSPredicate(format: "X == 1") 
    let predicate2 = NSPredicate(format: "Y == 2") 
    let predicateCompound = NSCompoundPredicate.init(type: .or, subpredicates: [predicate1,predicate2]) 

स्विफ्ट 3 - और

let predicate1 = NSPredicate(format: "X == 1") 
    let predicate2 = NSPredicate(format: "Y == 2") 
    let predicateCompound = NSCompoundPredicate.init(type: .and, subpredicates: [predicate1,predicate2]) 
+0

इसे प्यार करो! मेरा कोड इस –

+0

नाइस कोड की तरह बहुत अच्छा दिखता है ... मेरे लिए काम किया। ऊपर उठाया !!! – NSPratik

संबंधित मुद्दे