Invalid operations to binary expression ('float' and 'id') - objective-c

I'm getting this error
Invalid operations to binary expression ('float' and 'id')
NSMutableArray *redValues = [NSMutableArray array];
NSUInteger *redValuesLength = [redValues count];
NSMutableArray *arrayOne = [NSMutableArray array];
NSInteger j;
float diffForAverage, totalOne;
__block int counter = 0;
float average = totalOne / amount;
int amount = 1;
for (j = (counter + 25); j < (redValuesLength - 25); j++)
{
diffForAverage = average - redValues[j + 1]; // error occurs here
if (diffForAverage > -1 && diffForAverage < 1)
{
totalOne += redValues[j + 1]; // error occurs here
amount++;
[arrayOne addObject:[NSNumber numberWithInt:(j - 25)]];
counter++;
}
}
How can I solve this?

Please don't retype error messages (or code) when you post a question. Copy and paste. Otherwise you make mistakes. You can copy Xcode error messages out of the Issue Navigator. Default shortcut: ⌘4.
The actual error message is
Invalid operands to binary expression ('float' and 'id')
The problem is that redValues is an NSMutableArray, so its elements are objects (like NSObject), not primitive numbers (like float and int). The id type is “object identity”, and can refer to any Objective-C object, even those (extremely rare) objects that are not instances of NSObject.
You cannot add a float to an object reference, and you cannot store primitive numbers in an NSMutableArray.
You already know about the NSNumber wrapper object because you create one later in the code. You need to store NSNumber instances in redValues. Perhaps you already are doing that. Then when you get an NSNumber back out of redValues, you need to turn it back into a float to do math on it, like this:
diffForAverage = average - [redValues[j + 1] floatValue]; // error occurs here
If you declare your NSMutableArray like
NSMutableArray<NSNumber *> *redValues = [NSMutableArray array];
then the compiler knows that each element is an NSNumber and you can use the dot syntax (which some people prefer) like
diffForAverage = average - redValues[j + 1].floatValue; // error occurs here

Related

When accessing my NSMutableArray I get an error message like "Cannot initialize a variable of type 'int' with an rvalue of type 'id'"

I have the following function and I am struggling to get the y value out as an int.
+ (NSMutableArray *) cleanPoints:(NSMutableArray *)pointsArray{
NSMutableArray *mutableArray = [NSMutableArray array];
for(int i = 0; i<pointsArray.count-1; i++){
CLog(#"pointsArray %#", pointsArray[i]); /// here it gives me the correct number, like 345
int y = (int)pointsArray[i]; //// here seems to be the problem
CLog(#"y = %d", y); ///// y is a weird number, like y = 384643392
if (y < 4 || y > -4){
y = 0;
}
//create Array
[mutableArray addObject:#(y)];
}
return mutableArray;
}
If I take out the (int) from the int y = (int)pointsArray[I] line then I get the error "Cannot initialize a variable of type 'int' with an rvalue of type 'id'
This line makes no sense:
int y = (int)pointsArray[i];
It is impossible for an NSArray to contain int values. It can contain only objects, and in Objective-C an int is not an object.
Perhaps you mean
int y = [pointsArray[i] intValue];
(but I’m just guessing that this NSArray contains NSNumber objects; I have no way of knowing, as you have given no information about that)

Calculating value of K without messages

Question:
Find the value of K in myInterViewArray without any messages/calls
I was given this hint:
The numbers in the array will never exceed 1-9.
NSArray *myInterViewArray = #[#2,#1,#3,#9,#9,#8,#7];
Example:
If you send 3, the array will return the 3 biggest values in myInterViewArray * 3. So in the example below, K = 9 + 9 + 8.
--
I was asked this question a while back in an interview and was completely stumped. The first solution that I could think of looked something like this:
Interview Test Array:
[self findingK:myInterViewArray abc:3];
-(int)findingK:(NSArray *)myArray abc:(int)k{ // With Reverse Object Enumerator
myArray = [[[myArray sortedArrayUsingSelector:#selector(compare:)] reverseObjectEnumerator] allObjects];
int tempA = 0;
for (int i = 0; i < k; i++) {
tempA += [[myArray objectAtIndex:i] intValue];
}
k = tempA;
return k;
}
But apparently that was a big no-no. They wanted me to find the value of K without using any messages. That means that I was unable to use sortedArrayUsingSelector and even reverseObjectEnumerator.
Now to the point!
I've been thinking about this for quite a while and I still can't think of an approach without messages. Does anyone have any ideas?
There is only one way to do that and that is bridging the array to CF type and then use plain C, e.g.:
NSArray *array = #[#1, #2, #3];
CFArrayRef cfArray = (__bridge CFArrayRef)(array);
NSLog(#"%#", CFArrayGetValueAtIndex(cfArray, 0));
However, if the value is a NSNumber, you will still need messages to access its numeric value.
Most likely the authors of the question didn't have a very good knowledge of the concept of messages. Maybe they thought that subscripting and property access were not messages or something else.
Using objects in Obj-C without messages is impossible. Every property access, every method call, every method initialization is done using messages.
Rereading the question, they probably wanted you to implement the algorithm without using library functions, e.g. sort (e.g. you could implement a K-heap and use that heap to find the K highest numbers in a for iteration).
I assume what is meant is that you can't mutate the original array. Otherwise, that restriction doesn't make sense.
Here's something that might work:
NSMutableArray *a = [NSMutableArray array];
for (NSNumber *num in array) {
BOOL shouldAdd = NO;
for (int i = a.count - 1; i >= k; i--) {
if ([a[i] intValue] < [num intValue]) {
shouldAdd = YES;
break;
}
}
if (shouldAdd) {
[a addObject:num];
}
}
int result = a[a.count - k];
for (int i = k; k < a.count; k++) {
result += [a[i] intValue];
}
return result;

Why would a function defined in the same class be considered undeclared? How to declare it properly?

I'm getting the error "undeclared identifier" on the commented line:
- (BOOL) isInIntArray:(NSInteger[])array theElem:(int)elem{
int i = 0;
NSInteger sizeOfArray = (sizeof array) / (sizeof array[0]);
while(i < sizeOfArray){
if(array[i] == elem){
return TRUE;
}
i++;
}
return FALSE;
}
- (int)getNextUnusedID{
int i = rand()%34;
while ([isInIntArray:idsUsed theElem:i]) { //here: Use of undeclared identifier 'isInIntArray'
i = rand()%34;
}
return i;
}
I really don't understand why, they are in the same .m file.
Why would that be?
Also, this code:
NSInteger sizeOfArray = (sizeof array) / (sizeof array[0]);
is giving me the warning:
Sizeof on array function will return Sizeof 'NSInteger *' (aka: 'int *') instead of 'NSInteger[]'"
How should I properly determine the size of an array?
It looks like you've missed out self from this line
while ([isInIntArray:idsUsed theElem:i])
This should be:
while ([self isInIntArray:idsUsed theElem:i])
As #CaptainRedmuff pointed out, you are missing the target object in method invocation, that is self.
//[object methodParam:x param:y];
[self isInIntArray:idsUsed theElem:i];
To your second Q. In C language you cannot determine the size of an array. That's why they are not used, since we have objects for this. I recommend you to use these:
NSMutableArray *array = [[NSMutableArray alloc] init]; // to create array
array[0] = #42; // to set value at index, `#` creates objects, in this case NSNumber
[array insertObject:#42 atindex:0]; // equivalent to the above
NSInteger integer = array[0].integerValue; // get the value, call integerMethod to get plain int
integer = [[array objectAtIndex:0] integerValue]; // equivalent to the above
[array containsObject:#42]; // test if given object is in the array
[array indexOfObject:#42]; // get index of object from array, NSNotFound if not found
array.count; // to get the number of objects
Important: These arrays have variable size and they are not limited! But you can access elements only at indexes 0..(n-1) (where n in number of objects) and you can set values only for indexes 0..n.
In other words, you can not do array[3] = #42; for empty array, you need to fill first 3 positions first (indexes 0, 1 and 2).
write this in .h file (declare the function)
- (BOOL) isInIntArray:(NSInteger[])array theElem:(int)elem;
and call the method using following way
while ([self isInIntArray:idsUsed theElem:i]) { //here: Use of undeclared identifier 'isInIntArray'
i = rand()%34;
}

float [] array problem in objective c

I am coding in xcode by objective c. I came up with a problem.
I want to try like
declare float[] weights;
results looks like this
weight[0] = 0.5
weight[1] = 0.4
weight[2] = 0.9
A.h
NSMutableArray *weight;
A.m
weights = [NSMutableArray array];
for(int i=0; i < 4; i++) {
float randomNumber = arc4random() % 11;
[weights addObject:[[NSNumber alloc] initWithFloat:randomNumber]];
NSLog(#" for loops color prob weghts=%f",[weights objectAtIndex:i] );
}
I don't know what is wrong with this code. Please help me to find out?
When I print it by NSLOG " all [weight = 0.000] and also How do I access like [weight floatvalue].
secondly, when I create this class to another class there are weight [0],[1],[2],[3] and no values
It should be [[weights objectAtIndex:i] floatValue] when you print it in your NSLog
NSNumber is a class, not a integral type.
Therefore, you must use %#, not %f.
NSLog(#" for loops color prob weghts=%#",[weights objectAtIndex:i] );
Alternatively, use floatValue, like you said. You may need to cast the object into NSNumber first (for type safety)
NSNumber *number = (NSNumber *)[weights objectAtIndex:i];
NSLog(#" for loops color prob weghts=%f", [number floatValue]);
Also, you are leaking objects here, because you did not release them after putting them in the array. Either release after placing them in array, or use [NSNumber numberWithFloat:]

Creating a C Array from 2D NSArray

I have a 2D NSArray of string numbers that I would like to convert to a 2D C array of doubles for use with BLAS/LAPACK functions (through the accelerate framework).
This line of code seems to work, however seems to be incredibly inefficient and eventually crashes due to a malloc error. Is there a more efficient way to convert this 2D NSArray to a C array? Or a convienent way of using NSArrays with BLAS/LAPACK?
double gridDataC[[nrows intValue]+1][[ncol intValue]+1];
for(i=6;i<[fileLines count]-1;i++){
for(j=0;j<[ncol intValue]-1;j++){
gridDataC[i][j]=[[[[fileLines objectAtIndex:i] componentsSeparatedByString:#" "] objectAtIndex:j] doubleValue];
}
}
fileLines is an array that contains lines of a file that are parsed into respective numbers.
There are few things here that deal with memory.
1.componentsSeparatedByString: creates an autoreleased array. Since you're looping for every object within that string, you are creating similar array multiple times. As the autoreleased objects are not released until the end of the runloop this might clog the memory. It's better to do this once by bringing the method call out of the inner loop.
2.The value of i is the most confusing. You pass i as the index for gridDataC. It should probably be i - 6 if you're starting from i = 6.
double gridDataC[[nrows intValue] + 1][[ncol intValue] + 1];
for( i = 6; i < [fileLines count] - 1; i++ ){
NSArray * components = [[fileLines objectAtIndex:i] componentsSeparatedByString:#" "];
for( j = 0; j < [ncol intValue] - 1; j++ ){
gridDataC[i - 6][j] = [[components objectAtIndex:j] doubleValue];
}
}