0

The following code which was sourced from the internet does not appear to be behaving correctly. The NSPredicate is returning the object value rather than the property value of that object which is a string. (See output below). Has anyone seen this before?

If you believe this correct then how do I print the string value?

// Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *age;
@end

.

// ViewControll.m

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSArray *firstNames = @[ @"Alice", @"Bob", @"Charlie", @"Quentin" ];
    NSArray *lastNames = @[ @"Smith", @"Jones", @"Smith", @"Alberts" ];
    NSArray *ages = @[ @24, @27, @33, @31 ];

    NSMutableArray *people = [NSMutableArray array];
    [firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        Person *person = [[Person alloc] init];
        person.firstName = firstNames[idx];
        person.lastName = lastNames[idx];
        person.age = ages[idx];
        [people addObject:person];
    }];

    NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];
    NSPredicate *smithPredicate = [NSPredicate predicateWithFormat:@"lastName = %@", @"Smith"];
    NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];

    // ["Bob Jones"]
    NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);

    // ["Alice Smith", "Charlie Smith"]
    NSLog(@"Smiths: %@", [people filteredArrayUsingPredicate:smithPredicate]);

    // ["Charlie Smith", "Quentin Alberts"]
    NSLog(@"30's: %@", [people filteredArrayUsingPredicate:thirtiesPredicate]);
}

@end

Output

2014-08-12 17:51:31.526 NSPredicate[41013:60b] Bobs: (
    "<Person: 0x10931c720>"
)
2014-08-12 17:51:31.527 NSPredicate[41013:60b] Smiths: (
    "<Person: 0x10931cf60>",
    "<Person: 0x10931c110>"
)
2014-08-12 17:51:31.527 NSPredicate[41013:60b] 30's: (
    "<Person: 0x10931c110>",
    "<Person: 0x10931ca30>"
)
user3626407
  • 287
  • 1
  • 6
  • 15
  • The code is doing exactly what it's supposed to do. What string value do you want to print? The first and last name? Then you have to write code to do that. – Colin Aug 12 '14 at 17:05
  • Look at the comments above the 3 NSLogs. Thats the strings i'm expecting to see. How do I achieve this? – user3626407 Aug 12 '14 at 17:10

2 Answers2

1

NSPredicate is behaving as it should.

NSPredicate will return every object that meets your predicate specifications. It will not return the property values that you're looking for.

If you believe this correct then how do I print the string value?

Simple: NSPredicate returns you the objects with the properties you want, so just ask each object for their properties!

NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];

// ["Charlie Smith", "Quentin Alberts"]
NSArray *peopleOver30 = [people filteredArrayUsingPredicate:thirtiesPredicate];
for (int i = 0; i < peopleOver30.count; i++) {
    Person *person = peopleOver30[i];
    NSLog(@"First Name: %@, Last Name: %@, Age: %@", person.firstName, person.lastName, person.age);
}

Expected Output:

 2014-08-12 17:51:31.526 NSPredicate[41013:60b] First Name: Charlie Last Name: Smith Age: 33
 2014-08-12 17:51:31.526 NSPredicate[41013:60b] First Name: Quentin Last Name: Alberts Age: 31
Daniel Brim
  • 507
  • 3
  • 10
0

As you are using custom class to hold the data. when you try to print values using NSLog it will print the address of the person object You have to use the description method inside your Person class to print all the attributes

-(NSString *)description{

return @"FirstName: %@, LastName: %@, E-mail: %@", 
                    _firstName, _lastName, _email;

}

Here is same reference question Click here!

Community
  • 1
  • 1
Prashant
  • 101
  • 5