I have multiple category list(around 45). i want to show some of the category to first like (Helicopter,Lake Monster,Dinosaur Attack) that will come at the starting after this remaning other will come. i have used the following code.
That works fine. But its to lengthy. so i want to filter this code.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF IN %#", #[#"Helicopter", #"Lake Monster",#"Dinosaur Attack"]];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Helicopter"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Lake Monster"];
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Dinosaur Attack"];
NSMutableArray *filteredArray = [[NSMutableArray alloc]init];
NSArray *arr1=[packages filteredArrayUsingPredicate:predicate1];
NSArray *arr2=[packages filteredArrayUsingPredicate:predicate2];
NSArray *arr3=[packages filteredArrayUsingPredicate:predicate3];
[filteredArray insertObject:[arr1 objectAtIndex:0] atIndex:0];
[filteredArray insertObject:[arr2 objectAtIndex:0] atIndex:1];
[filteredArray insertObject:[arr3 objectAtIndex:0] atIndex:2];
[packages removeObject:[arr1 objectAtIndex:0]];
[packages removeObject:[arr2 objectAtIndex:0]];
[packages removeObject:[arr3 objectAtIndex:0]];
So is there any way to achieve this result with shortest method?
Just cleaning up your own code, you could do the following:
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Helicopter"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Lake Monster"];
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:#"packageName CONTAINS[cd] %#", #"Dinosaur Attack"];
NSMutableArray *filteredArray = [[NSMutableArray alloc]init];
for (NSPredicate *predicate in #[predicate1, predicate2, predicate3]) {
NSArray *arr=[packages filteredArrayUsingPredicate:predicate];
[filteredArray addObject:arr[0]];
[packages removeObject:arr[0]];
}
You should probably create a class (lets call it STOElement) that has two properties, (NSString*)text, and (NSNumber*)order. Create an instance of that class for each element 'Helicopter' etc, set that as the text, and then set the order you would like that element to appear in as the order (1,2,3 etc).
Then use the sortedArrayUsingComparator: to get an array with the order you want
NSArray* sortedArray = [arrayOfElements sortedArrayUsingComparator:^NSComparisonResult(STOElement* element1, STOElement* element2) {
return [element1.order compare:element2.order];
}];
Related
I have array of custom objects, _momsArray. shown here is single object of such array:
Custom *yourMom {
name = #"Sally M. Brown";
age = 54;
weight = 43.2;
}
I run my predicate inside searchBar delegate:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if ([searchText length]<=0) {
_tableDataArr = [[NSMutableArray alloc] initWithArray:_momsArray];
} else{
// filtered _tableDataArr
NSString *filter = #"name BEGINSWITH[cd] %#";
NSPredicate* predicate = [NSPredicate predicateWithFormat:filter, searchText];
NSArray *filteredArr = [_momsArray filteredArrayUsingPredicate:predicate];
_tableDataArr = [[NSMutableArray alloc] initWithArray:filteredArr];
}
[_momTable reloadData];
}
This doesn't give expected result. For example, when I type S, sally doesn't appear at all. What is wrong with my code?
EDIT: The string in the custom objects contains punctuations and therefore it is not the same as other answers.
To filter an array with custom objects you can use this code.
NSString *str = #"text";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.name contains[c] %#", str];
NSArray *arrFiltered = [self.arrDataObject filteredArrayUsingPredicate:predicate];
Hope, it helps.
Your string is not properly generated so use below code :
NSPredicate *predicate = [ NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", text];
arrFilterData = [NSArray arrayWithArray:[arrDataList filteredArrayUsingPredicate:predicate]];
OUTPUT
Before search
After search
And with code
NSPredicate *predicate = [ NSPredicate predicateWithFormat:#"SELF CONTAINS[c] %#", text];
arrFilterData = [NSArray arrayWithArray:[arrDataList filteredArrayUsingPredicate:predicate]];
OutPut:
Edit
Output :
Use this code :
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", searchText];
NSMutableArray *filteredArr = [[_momsArray filteredArrayUsingPredicate:pred]mutableCopy];
NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd]%#",#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
I am aware that arrFiltered will contain the result ABCD and ABCE.
But, I want the result as CDE.
Is there a way to find the inverse of the predicate specified. ie., !(ABC)
Try to use NOT with predicate
NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (SELF CONTAINS[cd] %#"),#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
try
[NSPredicate predicateWithFormat:#"SELF !=[c] %#",#"ABC"];
The [c] makes the equality comparison case-insensitive.
Option-2
NSArray *arrValues = [NSArray arrayWithObjects:#"ABCD",#"ABCE",#"CDE",nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (SELF CONTAINS %#)",#"ABC"];
NSArray *arrFiltered = [arrValues filteredArrayUsingPredicate:predicate];
you get output as
I would like to know how if at all to use a compound NSPredicate?
I have made an attempt as follows however the currentInstall array is exactly the same at the start as it is after the predicate has been applied.
NSArray *currentInstall = [coreDataController filterReadInstalls:selectedInstallID];
NSArray *tempArray = [currentInstalls filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"cHR == 0"]];
currentInstalls = [tempArray copy];
NSPredicate *predicateAreaString = [NSPredicate predicateWithFormat:#"area == %#", [myFilter objectForKey:#"area"]];
NSPredicate *predicateBString = [NSPredicate predicateWithFormat:#"stage == %#", [myFilter objectForKey:#"area2"]];
NSPredicate *predicateCString = [NSPredicate predicateWithFormat:#"partCode == %#", [myFilter objectForKey:#"area3"]];
NSPredicate *predicateDString = [NSPredicate predicateWithFormat:#"doorNo CONTAINS[cd] %#", [myFilter objectForKey:#"door"]];
NSPredicate *predicateEString = [NSPredicate predicateWithFormat:#"doorDesc CONTAINS[cd] %#", [myFilter objectForKey:#"doorDesc"]];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[predicateAreaString, predicateBString, predicateCString, predicateDString, predicateEString]];
NSMutableArray *filteredArray = [NSMutableArray arrayWithArray:[currentInstalls filteredArrayUsingPredicate:compoundPredicate]];
currentInstalls = [filteredArray mutableCopy];
There doesn't seem to be anything obviously wrong with the way you have implemented NSCompundPredicate. If you are not trying to And or Not predicates then I would say it is something wrong with your predicate formats and how they match the array you are filtering.
I would try to use just 2 of the predicates to create an NSCompundPredicate then get that working or see what is causing your issue. NSHipster also has some good info about NSPredicates.
Is there a way to setup a NSPredicate that will search for all items in an NSArray?
something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"group.name == %#", arrayOfNames];
Use "IN" instead of "==" if the right-hand side is an array or set:
[NSPredicate predicateWithFormat: #"group.name IN %#", arrayOfNames]
Yes you can use NSPredicate with NSArray like this
NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:#"foo" forKey:#"BAR"]];
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(BAR == %#)", #"foo"]];
i'm trying to filter a string array with this predicate:
[NSPredicate predicateWithFormat:#"SELF LIKE[c] '#*!%d'", aNumber]
Every string which is like #WILDCARD!ANY_NUMBER is valid.
But it doesn't work :(
Can you help me?
EDIT:
NSString *pattern = [#"#*!" stringByAppendingFormat:#"%d", numberVariable];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pattern];
NSArray *filteredArray = [anArray filteredArrayUsingPredicate:pred];
The array anArray contains Strings like #0!-1 (numberVariable is -1) but the array filterdArray is empty. So the regex doesn't work.
EDIT:
My Solution:
NSString *pattern = [#"#.*!\\" stringByAppendingFormat:#"%d", numberVariable];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pattern];
NSArray *filteredArray = [anArray filteredArrayUsingPredicate:pred];
To find all strings that look like "#ANY_CHARACTERS!ANY_NUMBER" with an arbitrary number, you need the "MATCHES" operator with a regular expression:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", #"#.*!\\d+"];
NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
If you have a specific number aNumber and want to find all strings of the form
"#ANY_CHARACTERS!<aNumber>", then the following should work:
NSString *pattern = [#"#*!" stringByAppendingFormat:#"%d", aNumber];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF LIKE %#", pattern];
NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
The problem with your
[NSPredicate predicateWithFormat:#"SELF LIKE[c] '#*!%d'", aNumber]
is that %d inside quotation marks is not replaced by aNumber.