Learn Iphone
Learn Iphone

Reputation: 9

How I can check data types of NSArray objects in case of float and int values?

Check Following Code and create an if condition to check an element type float and integer. I have used but fail to compare float value.

NSArray *a=[[NSArray alloc] initWithObjects:@"C",[NSNumber numberWithInt:120],[NSNumber numberWithFloat:333.222],[NSDate date], nil]; 

for (NSObject *x in a) 
{
    NSLog(@"%@",x);

    if([x isKindOfClass: [NSNumber class]])
    {
        //How i check float type with nsnumber
        NSLog(@"Integer Exist");
    }
    else if([x isKindOfClass:[NSString class]])
    {
        NSLog(@"String Exist");   
    }
    else if([x isKindOfClass:[NSDate class]])
    {
        NSLog(@"Date Exist");
    }
}

Upvotes: 1

Views: 678

Answers (4)

Chris Devereux
Chris Devereux

Reputation: 5473

There isn't separate class for integer and floating point numbers. NSNumber is used for both. As others have mentioned, NSNumber has an objCType method, which will return a string representing a C number type, such as int or float.

However...

Don't assume that it will return the type you created the NSNumber with. NSNumber is free to use any type capable of representing the number. Often it will choose smaller types to save memory.

For example, you might assume that calling objcType on each member of this array:

NSArray *myArray = @[@1.2, @3.0f, @false];

will return a "d" (double), "f" (float) and "b" (bool).

It won't. It might return a "f" (float), "c" (char) and "c" (char)`. Or all floats. Or all doubles. Exactly what it returns is an implementation detail that may vary between OS releases.

If you just want to check whether a given NSNumber contains an integer or not, you should grab the doubleValue and check yourself:

BOOL isInteger = abs(ceil(myNumber.doubleValue) - myNumber.doubleValue) < DBL_EPSILON;

If you need to distinguish between, eg., 1.00 and 1, you'll need to wrap your NSNumber inside another object that contains the additional information. As mentioned above, this information is thrown away when an NSNumber is created. Eg:

@interface MyNumber : NSObject
@property (strong, nonatomic) NSNumber *number;
@property (assign, nonatomic) BOOL isInteger;
@end

Upvotes: 2

Rajneesh071
Rajneesh071

Reputation: 31081

1st way

NSNumber *num=[NSNumber numberWithFloat:4.3];
if ( strcmp([num objCType], @encode(float)) == 0 ) {
    NSLog(@"Float value");
}

2nd way

NSNumber *num=[NSNumber numberWithFloat:4.3];
NSString *str=[NSString stringWithFormat:@"%@",num];
NSArray *ary=[str componentsSeparatedByString:@"."];
if ([ary count]>1) {
    NSLog(@"Float value");
}

Upvotes: 0

Sumit Mundra
Sumit Mundra

Reputation: 3901

If you only care about classes you can use isKindOfClass:, but if you want to deal with scalars you are correct that you need to use property_getAttributes(), it returns a string that encodes the type information. Below is a basic function that demonstrates what you need to do. For examples of encoding strings, look here.

unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([object class], &outCount);
for (i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    char *property_name = property_getName(property);
    char *property_type = property_getAttributes(property);

    switch(property_type[1]) {
      case 'f' : //float
        break;
      case 's' : //short
        break;
      case '@' : //ObjC object
        //Handle different clases in here
        break;
    }
}

Upvotes: 0

Alexander
Alexander

Reputation: 8147

NSNumber has objCType method (inherited from NSValue)

Example for a float check:

if ( strcmp([x objCType], @encode(float)) == 0 ) {
    // float value
}

Upvotes: 5

Related Questions