How can I create an NSArray with float values - objective-c

I want to make a float value array. How can I do this? My code is:
NSArray *tmpValue = [[NSArray alloc] init];
total = total + ([[self.closeData objectAtIndex:i]floatValue] - total)* expCarpan;
firstValue = total;

NSArrays only take object types. You can add various non-object types to an NSArray by using the NSNumber wrapper:
NSNumber *floatNumber = [NSNumber numberWithFloat:myFloat];
[myArray addObject:floatNumber]; // Assuming `myArray` is mutable.
And then to retrieve that float from the array:
NSNumber *floatNumber = [myArray objectAtIndex:i];
float myFloat = [floatNumber floatValue];
(As you have done in your code above).
Update:
You can also use the NSValue wrapper in the same way as NSNumber for other non-object types, including CGPoint/Size/Rect/AffineTransform, UIOffset/EdgeInsets and various AV Foundation types. Or you could use it to store pointers or arbitrary bytes of data.

The NSArray class can only contain instances of other Objective-C objects. Fortunately, Apple already has several Objective-C object types for encapsulating C primitive types. For instance, NSNumber can incapsulate many different types of C numbers (integers, floats, etc.). NSValue can incapsulate arbitrary structures, CGPoints, pointers, etc. So, you can use NSNumber and float in conjunction with NSArray as follows:
NSArray * myArray;
NSNumber * myFloatObj = [NSNumber numberWithFloat:3.14];
myArray = [NSArray arrayWithObjects:myFloatObj, nil];
You can then get the original float value from the first NSNumber of the array:
NSNumber * theNumber = [myArray objectAtIndex:0];
float theFloat = [theNumber floatValue];
Alternatively, you can turn this into a one-liner:
float theFloat = [[myArray objectAtIndex:0] floatValue];

Primitive types can't be included in a NSArray, which is only for objects. For numbers, use NSNumber to wrap your floats.
NSNumber *n1 = [NSNumber numberWithFloat:1.2f];
NSNumber *n2 = [NSNumber numberWithFloat:1.4f];
NSArray *array = [NSArray arrayWithObjects:n1, n2, nil];

Related

iOS - CLLocationCoordinate2D/floats/long into a NSDictionary for JSON?

I'm looking to convert a simple objectiveC class (not even that at the minute its just some vars in a function) to JSON so that it can be sent and impretated into a java object at the server side.
The Class might have the following fields;
LatLng locationA // a simple POJO with either float or long to represent lat and long.
LatLng locationA
float someFloat
It the minute I am tring to pack everything in to a NSDictonary. Passing the floats in didn't work so I has to convert them to NSStrings. So on the server side they would arive as strings.. which isnt ideal.
CLLocationCoordinate2D location = ... ;
float lat = location.latitude;
float lng = location.longitude;
float aFloat = 0.12434f;
NSString *aFloatstr = [NSString stringWithFormat:#"%f", aFloat];
NSString *latStr = [NSString stringWithFormat:#"%f", lat];
NSString *lngStr = [NSString stringWithFormat:#"%f", lng];
NSDictionary *locationDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
latStr , #"latitude",
lngStr, #"longitude",
nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
locationDictionary, #"locationA",
locationDictionary, #"locationB",
aFloatstr,#"aFloat",
nil];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#",str);
Whats the best way do putting CLLocationCoordinate2Ds into an NSDictionary?
How do I add primitative types, long floats ect.. to an NSDictionary?
Instead of putting the latitude and longitude into NSString, you'll have better luck with NSNumber. When NSJSONSerialization comes upon an NSNumber it won't quote the value like it would a string (which is what you want when transmitting numbers, right?).
You'll also want to use double, not float, for latitude and longitude, since that's how they're represented internally. No need to throw away precision.
[NSNumber numberWithDouble:lat]
[NSNumber numberWithDouble:lng]
[NSNumber numberWithFloat:aFloat]
Since instances of NSNumber are objects, you'll be able to store them in NSDictionary no problem.
Use NSNumber instead of strings to wrap the float values, e.g.:
NSDictionary *locationDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:lat] , #"latitude",
[NSNumber numberWithFloat:lng], #"longitude", nil];
That way, NSJSONSerialization will correctly encode them as numeric values.
Structs
Neat way of doing this is to create category for NSValue that understands your struct. In your case it's CLLocationCoordinate2D, but could be any really. Here is snippet from Apple's own documentation explaning usage of NSValue:
// NSValue+Polyhedron.h
typedef struct {
int numFaces;
float radius;
} Polyhedron;
#interface NSValue (Polyhedron)
+ (instancetype)valueWithPolyhedron:(Polyhedron)value;
#property (readonly) Polyhedron polyhedronValue;
#end
// NSValue+Polyhedron.m
#implementation NSValue (Polyhedron)
+ (instancetype)valueWithPolyhedron:(Polyhedron)value
{
return [self valueWithBytes:&value objCType:#encode(Polyhedron)];
}
- (Polyhedron) polyhedronValue
{
Polyhedron value;
[self getValue:&value];
return value;
}
#end
From here usage is quite trivial. To create boxed NSValue:
NSValue *boxedPolyhedron = [NSValue valueWithPolyhedron:yourStruct];
Now you can put boxedPolyhedron whenever NSValue can go, NSArray, NSDictionary, NSSet, and many more, plus al the mutable versions.
To get struct back:
Polyhedron polyStruct = [boxedPolyhedron polyhedronValue];
That's it.
As a bonus, this works for any C type, not only for structs.
floats, longs, etc.
As mentioned above, could do same as above. But, for numbers, you could use NSNumber which is actually a subclass if NSValue with all popular methods already implemented. Here is a list of types you can box by instantiating NSNumber:
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value;
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value;
In similiar fashion you un-box values using [yourNumber longValue], [yourNumber floatValue], etc.
Hope that helps.

floats in NSArray

I have an NSArray of floats which I did by encapsulating the floats using
[NSNumber numberWithFloat:myFloat] ;
Then I passed that array somewhere else and I need to pull those floats out of the array and perform basic arithmatic. When I try
[myArray objectAtIndex:i] ;
The compiler complains that I'm trying to perform arithmatic on a type id. It also won't let me cast to float or double.
Any ideas? This seems like it should be an easy problem. Maybe it will come to me after another cup of coffee, but some help would be appreciated. Thanks.
You can unbox the floats like this:
float f = [[myArray objectAtIndex:i] floatValue];
Unbox the float value from the NSNumber object thusly:
NSNumber *number = myArray[i];
float f = [number floatValue];
Your are converting float value to NSNumber object and adding it to NSArray.So you have to again convert NSNumber object to float value.
NSNumber *number = [yourArray objectAtIndex:0];
float f = [number floatValue];

Array of doubles objective c

Is there something like NSMutableArray that will take doubles directly without putting them inside the #""?
You can only put objects into an NSMutableArray. But you can wrap your doubles in NSNumber like so:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
[array addObject:[NSNumber numberWithDouble:0.12345]];
[array addObject:[NSNumber numberWithDouble:5.43210]];
You can only insert objects into an NSMutableArray. Luckily, there is a class, NSNumber, that is used to wrap Objective-C primitives as objects. You can use the doubleValue method to get your primitive value back.
For example:
NSMutableArray *numArray = [[NSMutableArray alloc]initWithObjects:[NSNumber numberWithDouble:1.1f], nil];
double num = [[numArray objectAtIndex:0]doubleValue];

How to assign integer from NSMutableArray

I would like to assign NSInteger by using NSMutableArray is there any way to solve this?
It is not working on simulator and cut off when run the application.
NSInteger Section;
NSMutableArray dataSourceSection;
Section = (NSInteger)[dataSourceSection objectAtIndex:2];
Thank you.
A NSMutableArray only stores objects. NSInteger is not an object, but a primitive data type. There is a class NSNumber, however, that can be used instead to store numeric values inside objects. Here's one example.
NSNumber *five = [NSNumber numberWithInteger:5];
NSMutableArray *numbers = [NSMutableArray array];
[numbers addObject:five];
To get the object back and retrieve the integer value use,
NSNumber *firstNumber = [numbers objectAtIndex:0];
NSInteger valueOfFirstNumber = [firstNumber integerValue];
you can't pull an NSInteger out of an NSMutableArray, basically because you can't put anything rather than objects in. in your case NSNumber would be the way to put numbers in NSMutablearray. if you do so you can easily get hold of your object, which is an NSNumber, and convert it to a NSInteger by:
NSMutableArray *array = [[NSMutableArray alloc] init];
// populate the array with NSNumbers
NSInteger number = [[array objectAtIndex:2] intValue];

How do I access floats from a dictionary of floats?

I have a property list (Data.plist) that contains an array of two dictionaries. Each dictionary is filled with key names (Factor 1, Factor 2, etc) and floats (0.87, 1.15, etc.). I am trying to access the numbers stored in the dictionary. First I load the dictionary using:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Data.plist"];
NSArray *plistData = [[NSArray arrayWithContentsOfFile:finalPath] retain];
NSDictionary *dictionaryOne = [plistData objectAtIndex:0];
Actually accessing the numbers stored is where I'm having a problem:
Float32 conversionFactor = [scyToLCMMen objectForKey:"Factor 50"];
I'm getting the error: "incompatible types in initialization". What am I doing wrong? Is it not a Float32?
Objective-c containers can only hold obj-c types, so what you get is not a float for sure. What you probably have is NSNumber object and you need to "extract" plain float value from it:
Float32 conversionFactor = [[scyToLCMMen objectForKey:"Factor 50"] floatValue];
NSNumber *conversionFactor = [dictionaryOne valueForKey:#"Factor 50"];
float factor = [conversionFactor floatValue];
That's what I'd do
The value is likely an instance of NSNumber.
Float32 conversionFactor = [[scyToLCMMen objectForKey:"Factor 50"] floatValue];