7

I am trying to filter my array with two entities within an object like I have a Person object in which I have name, address, number, email, etc. I am trying to filter my array list of objects with just name and number. How can this be achieved with using NSPredicate?

occulus
  • 16,959
  • 6
  • 53
  • 76
topgun
  • 2,463
  • 8
  • 31
  • 46
  • I think [here is a good answer](http://stackoverflow.com/questions/958622/using-nspredicate-to-filter-an-nsarray-based-on-nsdictionary-keys). – Sergey Kalinichenko Dec 08 '11 at 19:35
  • What have you tried already? What happened? Have you checked the documentation or examples on the web? Did you search stackoverflow for similar questions? Did you have trouble understanding them? – occulus Dec 08 '11 at 19:40

4 Answers4

13

Create the predicate (the following assumes that your Person class has name and number string properties):

NSString *nameFilter = @"Steve*";
NSString *numberFilter = @"555-*";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name like %@) or (number like %@)", nameFilter, numberFilter];

Then, filter the array (this assumes you have an NSArray of Person objects):

NSArray *personArray = /* obtain from somewhere */;
NSArray *filtered = [personArray filteredArrayUsingPredicate:pred];

The result will be an array that contains Person objects whose name could be “Steve”, “Steven” etc, and whose number starts with 555-.

Edit

What you're saying doesn't really make sense. You can't remove properties from a class (or rather, you shouldn't). If you just want an array that contains only the names and numbers you'll have to iterate through the array of Person objects:

NSMutableArray *result = [NSMutableArray array];

for (Person *p in personArray)
    [result addObject:[NSString stringWithFormat:"%@ : %@", [p name], [p number]]];
Community
  • 1
  • 1
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • what if I don't want to use name like but I want all the names and numbers, then how do I set my predicate filter? – topgun Dec 08 '11 at 20:05
  • that's exactly what I was looking for, thanks. I think you can't do that similarly with nspredicate? Just curious if thats possible. – topgun Dec 08 '11 at 20:23
  • 1
    @kforkarim: Predicates are used to determine whether an object matches a set of rules or not, they aren't for transforming one object into another. – dreamlax Dec 08 '11 at 20:51
  • @kforkarim: If this is exactly what you were looking for, why did you accept the other answer? – dreamlax Dec 17 '11 at 11:23
  • because both answers are correct one way or another, just a different approach. – topgun Dec 19 '11 at 15:52
  • should be `for(NSObject* o in arr){...}` not `foreach` – BDR Jan 02 '15 at 09:43
  • @BDR: correct - I was probably confusing it for C#. – dreamlax Jan 04 '15 at 21:36
4

i believe you are looking for:

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"name==%@",name];

or if you want similarities for string names you could also use:

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"name like %@",name];

and assuming phone number is just an int, you could use ==, <, <=, etc for number comparisons

then apply it with:

NSArray * filteredarray  = [array filteredArrayUsingPredicate:predicate];
user1084563
  • 2,149
  • 17
  • 28
  • The thing is, if I do the way above, it will just list the array based on that name, but I want to delete all the rest of the entities and display just two entity. Guess I have to iterate through the for loop for that. – topgun Dec 08 '11 at 19:55
  • NSPredicate will remove all non matching entries from the array. It won't delete them from the array but it will return a second filtered array with just the objects that match the predicate – user1084563 Dec 08 '11 at 20:00
  • 1
    @kforkarim NSArray are immutable you can't delete items in them. Every method that would change an NSArray, will return a new array. If you are using NSMutableArray it's an other story, but here I don't think NSMutableArray are needed, you just need to take the return array and work with it. – Vincent Bernier Dec 08 '11 at 20:39
1

I prefer using CONTAINS word to do filtering. It's easy to do this job. Or you can combine them together:

NSPredicate * predicate =
 [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ OR name LIKE[cd] %@", filterName, filterName];

You can refer to OFFICIAL DOC:

BEGINSWITH: The left-hand expression begins with the right-hand expression.

CONTAINS: The left-hand expression contains the right-hand expression.

ENDSWITH: The left-hand expression ends with the right-hand expression.

LIKE: The left hand expression equals the right-hand expression: ? and * are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.

MATCHES: The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).

Kjuly
  • 34,476
  • 22
  • 104
  • 118
  • 1
    On an unrelated note, please don't [approve suggested edits](http://stackoverflow.com/review/suggested-edits/2763311) using backticks for emphasis, but reject or improve them - see e.g. [here](http://meta.gaming.stackexchange.com/q/7437/88) why – Tobias Kienzler Aug 21 '13 at 09:03
0
NSPredicate *pNewsCard = [NSPredicate predicateWithFormat:@"feedType = %@", @"NewsCard"];

NSArray *filteredNewsCard = [arrayTotalFeed filteredArrayUsingPredicate:pNewsCard];

feedType is the property of a Custom object to be compared and arrayTotalFeed is the array of Custom objects.

aashish tamsya
  • 4,903
  • 3
  • 23
  • 34
Anjali Prasad
  • 324
  • 2
  • 9