Array of floating point values in Objective-C - objective-c

How can I create array of floating point numbers in Objective-C?
Is it possible?

You can create a dynamic array (size decided at runtime, not compile time) in different ways, depending on the language you wish to use:
Objective-C
NSArray *array = [[NSArray alloc] initWithObjects:
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:2.0f],
[NSNumber numberWithFloat:3.0f],
nil];
...
[array release]; // If you aren't using ARC
or, if you want to change it after creating it, use an NSMutableArray:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
[array addObject:[NSNumber numberWithFloat:1.0f]];
[array addObject:[NSNumber numberWithFloat:2.0f]];
[array addObject:[NSNumber numberWithFloat:3.0f]];
...
[array replaceObjectAtIndex:1 withObject:[NSNumber numberWithFloat:99.9f]];
...
[array release]; // If you aren't using ARC
Or using the new-ish Objective-C literals syntax:
NSArray *array = #[ #1.0f, #2.0f, #3.0f ];
...
[array release]; // If you aren't using ARC
C
float *array = (float *)malloc(sizeof(float) * 3);
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;
...
free(array);
C++ / Objective-C++
std::vector<float> array;
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;

For an dynamic approach you can use NSNumber object and add it to NSMutableArray, or if you need only static array then use suggestions from comments, or use standard C.
like:
NSMutableArray *yourArray = [NSMutableArray array];
float yourFloat = 5.55;
NSNumber *yourFloatNumber = [NSNumer numberWithFloat:yourFloat];
[yourArray addObject:yourFloatNumber];
and then to retrive:
NSNumber *yourFloatNumber = [yourArray objectAtIndex:0]
float yourFloat = [yourFloatNumber floatValue];

If you are using Xcode 4.4+, you can try this:
NSArray *a = #[ #1.1f, #2.2f, #3.3f];
Here is all new literals of LLVM Compiler 4.0.

How about something like this?
#interface DoubleArray : NSObject
#property(readonly, nonatomic) NSUInteger count;
#property(readonly, nonatomic) double *buffer;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCount:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (double)valueAtIndex:(NSUInteger)idx;
- (void)setValue:(double)value atIndex:(NSUInteger)idx;
#end
#implementation DoubleArray
- (void)dealloc
{
if (_buffer != 0) {
free(_buffer);
}
}
- (instancetype)initWithCount:(NSUInteger)count
{
self = [super init];
if (self) {
_count = count;
_buffer = calloc(rows * columns, sizeof(double));
}
return self;
}
- (double)valueAtIndex:(NSUInteger)idx
{
return *(_buffer + idx);
}
- (void)setValue:(double)value atIndex:(NSUInteger)idx
{
*(_buffer + idx) = value;
}
#end
It's a basic array. You can extend this with more complex features like appending, indexed removal etc.

Related

objective-c. How to work with immutable Dictionary and return a copy?

I'm new in objective-c
The idea is that I'm passing a Dictionary to a method that return an altered Dictionary back.
I have a human "breath" method that expects as argument "air" Dictionary and returns another "air" dictionary.
test
-(void)testBreathIsConsumingTheRightAmountOfOxygen {
NSDictionary *oldAir = [[Environment alloc] init].air;
NSDictionary *newAir = [self.hummy breath:oldAir];
XCTAssertEqual([[newAir valueForKey:#"O2"] intValue], 995);
}
-(void)testBreathIsProducingTheRightAmountOfDioxide {
NSDictionary *oldAir = [[Environment alloc] init].air;
NSDictionary *newAir = [self.hummy breath:oldAir];
XCTAssertEqual([[newAir valueForKey:#"CO2"] intValue], 5);
}
code (my pour solution, I don't like it)
- (NSDictionary *) breath: (NSDictionary *) air {
int breathingStep = 5;
int oxygenOut = [[air valueForKey:#"O2"] intValue] - breathingStep;
int dyoxideOut = [[air valueForKey:#"CO2"] intValue] + breathingStep;
NSMutableDictionary *newAir = [NSMutableDictionary dictionaryWithDictionary:air];
[newAir setValue:[NSNumber numberWithInt:oxygenOut] forKey:#"O2"];
[newAir setValue:[NSNumber numberWithInt:dyoxideOut] forKey:#"CO2"];
return [NSDictionary dictionaryWithDictionary: newAir];
}
The *air Dictionary looks like this
[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:1000], #"O2", [NSNumber numberWithInt:0], #"CO2", nil ]
As a side note you should really be using the modern Objective-C syntax when dealing with NSDictionary and NSNumber.
I think you're looking for the mutableCopy method which returns a mutable version of the current dictionary.
- (NSDictionary *)breath:(NSDictionary *)air {
int breathingStep = 5;
NSMutableDictionary *newAir = [air mutableCopy];
newAir[#"O2"] = #([air[#"O2"] intValue] - breathingStep);
newAir[#"CO2"] = #([air[#"CO2"] intValue] + breathingStep);
return [NSDictionary dictionaryWithDictionary:newAir];
}
To make this better the keys (O2 and CO2) should be constant, for example:
NSString *const kBreathO2Key = #"O2";
NSString *const kBreathCO2Key = #"CO2";
Usage would be:
newAir[kBreathO2Key] = #([air[kBreathO2Key] intValue] - breathingStep);
To make this even better again it may be more appropriate to create a class to hold these values rather than a dictionary. Then you wouldn't need to convert between NSNumber and int.
#interface ASAir : NSObject
#property (nonatomic, assign) NSInteger O2;
#property (nonatomic, assign) NSInteger CO2;
#end
#implementation
#end
Then the breath: method could be improved as follows:
- (ASAir *)breath:(ASAir *)air {
int breathingStep = 5;
ASAir *newAir = [[ASAir alloc] init];
newAir.O2 = air.O2 - breathingStep;
newAir.CO2 = air.CO2 + breathingStep;
return newAir;
}

Why does NSMutablearray keep returning null?

I am generating a random equation say like 2*3+4..... and using DDMathparser to evaluate it. Here I have a class method which is supposed to return a random equation(stored inside a mutable array) only if it evaluates to a integer.
however it keeps returning Null and i can't figure out why. Please help me out.!
#import "Equation.h"
#import "DDMathParser.h"
#implementation Equation
-(NSMutableArray*)randEquation{
NSMutableArray* usableEquation=[[NSMutableArray alloc]init];
while(1){
NSArray *nums = #[#"1", #"2", #"3", #"4", #"5",#"6",#"7",#"8",#"9"];
unsigned index1=arc4random()%9;
NSString* num = [NSString stringWithFormat:#"%#", [nums objectAtIndex:index1]];
NSArray *symbols = #[#"+", #"-", #"*", #"/"];
unsigned index=arc4random()%4;
NSString* symb = [NSString stringWithFormat:#"%#", [symbols objectAtIndex:index]];
NSMutableArray *arrayOfSymbolsAndNumbers = [[NSMutableArray alloc] init];
for( int i=0;i<=10;i++){
if (i%2==0) {
[arrayOfSymbolsAndNumbers addObject:num];
}
else{
[arrayOfSymbolsAndNumbers addObject:symb];
}
}
NSMutableString *stringOfSymbolsAndNumbers=[[NSMutableString alloc]init];
for (NSObject * obj in arrayOfSymbolsAndNumbers)
{
[stringOfSymbolsAndNumbers appendString:[obj description]];
}
usableEquation=arrayOfSymbolsAndNumbers;
NSNumber *result=[stringOfSymbolsAndNumbers numberByEvaluatingString];
float resultFloat = [result floatValue];
float checker=resultFloat;
if (floor(checker)==checker) {
break;
}
else{
continue;
}
}
return usableEquation;
}
#end
NSLog(#"The content of array is%#",[equation randEquation]);
Based on your code, for this log to output The content of array is(null) means that equation is nil. Your randEquation (while not efficient) looks ok, the problem is that you haven't created the equation instance when you run the log statement.

Self and arrays problems

I am new to Objective C and I'm having trouble getting my head around a few things.
I am trying to make a big integer program, from which I read items entered in a string and put them into an individual elements in the array.
I am currently working on an add method which adds elements from both the arrays together to make a big number stored in a final array.
But I'm kind of confused about to get this array I made from the initWithString method into the array method. I have some understanding of self, but I don't really know how to use it in this sense.
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
NSMutableArray *intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
-(MPInteger *) add: (MPInteger *) x
{
//NSMutableArray *arr1 = [NSMutableArray arrayWithCapacity:100];
//NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:100];
//for (int i=0; i < 100; i++) {
//int r = arc4random_uniform(1000);
//NSNumber *n = [NSNumber numberWithInteger:r];
//[arr1 addObject:n];
//[arr2 addObject:n];
// }
self.array = [NSMutableArray initialize];
return x;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
MPInteger *x = [[MPInteger alloc] initWithString:#"123456789"];
MPInteger *y = [[MPInteger alloc] initWithString:#"123456789"];
[x add: y];
}
}
So I want too add the x and y arrays, but I'm not sure how to get the arrays in the add method. Do I use self to represent one of the arrays and initialise it, and x to represent the other. I don't know if I'm going about it completely the wrong way. Some help to understand would be greatly appreciated.
When referring to self you're actually accessing the current instance of the class. In other languages this may be implemented as this instead. There are a couple ways of designing the approach you're going for but the simplest pattern is probably composition:
#interface MPInteger
{
NSMutableArray *digits;
}
#end
----------------------------------------------------------------------------
#implementation MPInteger
-(id) initWithString: (NSString *) x
{
// Create a new instance of this class (MPInteger) with a default
// constructor and assign it to the current instance (self).
self = [super init];
if (self) {
// Previously we initialized a string, but then threw it out!
// Instead, let's save it to our string representation:
self->digits = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[self->digits addObject:ch];
}
return self;
}
// Depending on how you want to implement this function, it could return
// a new MPInteger class or update the current instance (self):
-(MPInteger *) add: (MPInteger *) x
{
NSArray *a = self->digits;
NSArray *b = x->digits;
// Have both strings for A + B, so use them to find C:
NSArray *c = ????;
// Return a new instance of MPInteger with the result:
return [ [ MPInteger alloc ] initWithString:c ];
}
#end
Notice that now the MPInteger class has an instance of an NSString object that will exist during the entire lifetime of the MPInteger object. To update/access this string, all you need to do is say:
self->digits

Seg Fault when using addObject to NSMutableArray

I seem to be having a problem with the NSMutableArray.
Here's my code:
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
while(condition) {
NSInteger temp = someNumber;
[returnArray addObject: temp];
}
But as soon as it hits the addObject message, the program seg faults. Any advice?
You can't add primitives like integers to an array, only objects (hence the name addObject:). If you want to add numbers, you have to convert them to an NSNumber, or one of the related classes.
You can only add objects to array and NSInteger is not an array.
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
while(condition) {
[returnArray addObject: [NSNumber numberWithInt: someNumber]];
}
You need to wrap primitives such as NSInteger into an NSNumber class. You can do the following:
while(condition)
{
NSInteger temp = someNumber;
[returnArray addObject:#(temp)];
}
Or if your compiler doesn't support that syntax:
while(condition)
{
NSInteger temp = someNumber;
[returnArray addObject:[NSNumber numberWithInteger:temp]];
}

How to exclude previously randomly selected NSArrays in loop

I'm new to Objective-C and I'm trying to create a simple dictionary style app for personal use. Right now I'm attempting to make a loop that prints randomly selected NSArrays that have been added to an NSDictionary. I'd like to print each array only once. Here is the code I'm working with:
NSArray *catList = [NSArray arrayWithObjects:#"Lion", #"Snow Leopard", #"Cheetah", nil];
NSArray *dogList = [NSArray arrayWithObjects:#"Dachshund", #"Pitt Bull", #"Pug", nil];
...
NSMutableDictionary *wordDictionary = [[NSMutableDictionary alloc] init];
[wordDictionary setObject: catList forKey:#"Cats"];
[wordDictionary setObject: dogList forKey:#"Dogs"];
...
NSInteger keyCount = [[wordDictionary allKeys] count];
NSInteger randomKeyIndex = arc4random() % keyCount;
int i = keyCount;
for (i=i; i>0; i--) {
NSString *randomKey = [[wordDictionary allKeys] objectAtIndex:randomKeyIndex];
NSMutableArray *randomlySelectedArray = [wordDictionary objectForKey:randomKey];
NSLog(#"%#", randomlySelectedArray);
}
This code prints the same array "i" times. Any pointers on how to exclude previously printed arrays from being printed again?
I'm wondering if removeObjectForKey: could be of any use.
You just need to re-calculate the random key index every time you go through the loop, and then, as you suggest, use removeObjectForKey:.
Something like this:
NSArray *catList = [NSArray arrayWithObjects:#"Lion", #"Snow Leopard", #"Cheetah", nil];
NSArray *dogList = [NSArray arrayWithObjects:#"Dachshund", #"Pitt Bull", #"Pug", nil];
//...
NSMutableDictionary *wordDictionary = [[NSMutableDictionary alloc] init];
[wordDictionary setObject: catList forKey:#"Cats"];
[wordDictionary setObject: dogList forKey:#"Dogs"];
//...
while ([wordDictionary count] > 0) {
NSInteger keyCount = [wordDictionary count];
NSInteger randomKeyIndex = arc4random() % keyCount;
NSString *randomKey = [[wordDictionary allKeys] objectAtIndex:randomKeyIndex];
NSMutableArray *randomlySelectedArray = [wordDictionary objectForKey:randomKey];
NSLog(#"%#", randomlySelectedArray);
[wordDictionary removeObjectForKey: randomKey];
}
In your code, you generate a random randomKeyIndex, then use it without changing its value i times in the loop. So you get i times the same array.
NSInteger randomKeyIndex = arc4random() % keyCount;
// ...
for (i=i; i>0; i--) {
NSString *randomKey = [[wordDictionary allKeys] objectAtIndex:randomKeyIndex];
// ...
}
As you say removeObjectForKey is an option for you, you can change your code into something like this:
NSInteger keyCount = [[wordDictionary allKeys] count];
for (i=keyCount; i>0; i--) {
NSInteger randomKeyIndex = arc4random() % keyCount;
NSString *randomKey = [[wordDictionary allKeys] objectAtIndex:randomKeyIndex];
NSMutableArray *randomlySelectedArray = [wordDictionary objectForKey:randomKey];
[wordDictionary removeObjectForKey:randomKey];
keyCount--;
NSLog(#"%#", randomlySelectedArray);
}