Add up all values from NSMutableArray - objective-c

I have a NSMutableArray, containing x different NSStrings (NSString but only numbers no letters). I would like to add up all of the values to return a single float, or int. I think I have to do this with a for loop, but i am very unfamiliar with for loops....
OK I have reached this point:
for (NSString *a in det)
{
float x = [a floatValue];
NSLog(#"%.2f",x);
}
And this returns all the values like this in ´NSLog`:
23.00
8.00
61.00
...
How could i just add them up now?

You can avoid looping and instead use the key value coding and obtain the total
NSMutableArray *arr = [NSMutableArray arrayWithObjects:#"1.1", #"2.2", #"3.1", nil];
NSNumber *sum = [arr valueForKeyPath:#"#sum.floatValue"];
Variable sum will be 6.4.

Try this:
float total = 0;
for(NSString *str in det)
{
total += [str floatValue];
}

Here is the code for a for-in if you want to save a bit of typing. It's preferable to use fast enumeration for these types of scenarios with data structures that support it.
float result = 0.0;
for(NSString *i in nsArray)
{
result += [i floatValue];
}

int result = 0;
for(int i=0;i<[array count];i++)
result += [[array objectAtIndex:i] intValue];
if you need to return a float simply define result as float and use floatValue instead of intValue

Related

valueForKeyPath: #"#max.self" not work when number is 100

NSArray *vals = {100,100,50,50,50}
maximumValue = [[vals valueForKeyPath: #"#max.self"] intValue];
Returns
maximumValue : 50
You probably have an array of strings. When compared as strings, "50" is greater than "100" because 5 comes after 1. You need to convert to integers first, then take the max.
Unfortunately, ObjC doesn't have the map function, so you need to do it manually.
NSMutableArray *intArray = [NSMutableArray array];
for (NSString *val in vals) {
[intArray addObject:#(val intValue)];
}
maximumValue = [[intArray valueForKeyPath: #"#max.self"] intValue];
Edit
Based on Sulthan's suggestion, you can also do the following:
NSArray *a = #[ #"50", #"100" ];
NSLog(#"%#", [[a valueForKeyPath:#"intValue"] valueForKeyPath:#"#max.self"]);
The first call to valueForKeyPath:#"intValue" gives an array of NSNumbers. At this point, the #max.self key-path gives the expected value, as a numeric comparison is made between elements.
NSArray *vals = #[#100,#100,#50,#50,#50];
NSLog(#"%d",[[vals valueForKeyPath: #"#max.self"] intValue]

How To Compare Integer to Objective-C enum

- (void)updateCheckBoxes {
NSArray *availableFuncUnits = _scanner.availableFunctionalUnitTypes;
for(int i = 0; i < [availableFuncUnits count]; i++) {
}
}
If I put a breakpoint inside the for loop, the elements of the NSArray * 'availableFuncUnits' are (__NSCFNumber *)(int)0 and (__NSCFNumber *)(long)3.
The array is supposed to contain elements of the following :
enum
{
ICScannerFunctionalUnitTypeFlatbed = 0,
ICScannerFunctionalUnitTypePositiveTransparency = 1,
ICScannerFunctionalUnitTypeNegativeTransparency = 2,
ICScannerFunctionalUnitTypeDocumentFeeder = 3
};
typedef NSUInteger ICScannerFunctionalUnitType;
Shouldn't I be able to do the following?
if([availableFuncUnits objectAtIndex:i] == ICScannerFunctionalUnitType.ICScannerFunctionalUnitTypeDocumentFeeder) {}
But it always gives me an error saying 'Expected identifier or '('.
How can I perform this comparison correctly? Thanks a lot for the help!
There are two problems that I see:
1) The array availableFuncUnits contains NSNumber objects. You cant directly compare them with primitive types (NSUInteger).
So your if should be like this:
ICScannerFunctionalUnitType type = [availableFuncUnits[i] integerValue]
if(type == ICScannerFunctionalUnitTypeDocumentFeeder){}
In your snippet you were comparing the pointer, not the object.
2) The error you were seeing is because the proper way to use enums is:
i = ICScannerFunctionalUnitTypeDocumentFeeder
You can't store integers in an NSArray because array's can only contain objects. To get integers into an array they must be wrapped with NSNumber:
NSInteger a = 100;
NSInteger b = 200;
NSInteger c = 300;
// Creating NSNumber objects the long way
NSArray *arrayOne = [NSArray alloc] initWithObjects:[NSNumber numberWithInteger:a],
[NSNumber numberWithInteger:b],
[NSNumber numberWithInteger:c], nil];
// Creating NSNumber objects the short way
NSArray *arrayTwo = [[NSArray alloc] initWithObjects:#100, #200, #300, nil];
This is relevant you your question because when you extract your NSNumber objects from your array, if you want to then compare them to actual integers, you must convert them back to integers (unwrap them).
NSLog(#"%d", [arrayOne firstObject] == 100); // COMPILER WARNING!!!
NSLog(#"%d", [[arrayOne firstObject] integerValue] == 100); // True
NSLog(#"%d", [[arrayTwo lastObject] integerValue] == 200); // False
This stage appears to be missing in your example.
Finally to compare your integer values with those from an enum, there's no need to reference the enum name, just use the individual values that make up the enum:
[[arrayTwo lastObject] integerValue] == ICScannerFunctionalUnitTypeFlatbed

Create array of floats from csv Objective C

I have once again a beginner problem. I have a CSV file that looks something like this:
3.4,2.4,6.30,2.2,53.42,54,1,5
Now, I have a code that can parse this into an array
NSError *error;
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"csv_file" ofType:#"csv" inDirectory:nil];
NSString *string = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
NSArray *array = [array componentsSeparatedByString:#","];
The issue I have is that I can't do math with these numbers (because they are char - or maybe string, not sure -).
My question is, Is there a way like I did but to create the array with floats, or is there a way to make the strings (or chars) in array into floats.
Thank you, and of course if my question isn't clear just let me know.
Let the elements in the array remain instances of NSString (this is what they are). Just when you access an element from the array make it a float like this:
float f = [array[index] floatValue];
You can't have NSArray of floats in Objective-C because NSArray may contain objects only.
You may be looking for the floatValue property
float sum = 0;
for (NSString *numberString in array) {
sum += [numberString floatValue];
}
If you want to put them in a C array:
float floatArray[array.count];
for(i = 0; i < sizeof(floatArray); i++) {
NSString *numberString = array[i];
floatArray[i] = [numberString floatValue];
}
Note that this way of creating a c array will add it to the stack; you'll need to use malloc if you want to add it to the heap.

Objective C - Array With Numbers

Is there a nicer way to fill an array with numbers than what I use?
It's crazy how much I got to write just to fill an array with numbers so they can be used for a calculation in a loop. This is easier in other C based languages like PHP, As3, or Java.
NSArray *myArray = [NSArray arrayWithObjects:
[NSNumber numberWithInt:1000],[NSNumber numberWithInt:237], [NSNumber numberWithInt:2673], nil];
int total = 0;
for(int i = 0; i < [myArray count]; i += 1 ){
total += [[myArray objectAtIndex: i]intValue];
NSLog(#"%i", total);
}
Hopefully there is a shorter way... I just want to fill an array with ints... cant be that hard
I guess you have to use NSNumber for an NSArray. If you want to use ints I guess you'd have to use a c array:
NSInteger myArray[20];
for (int i=0;i<20;i++) {
int num=myArray[i];
//do something
}
NSNumber though is I guess the better approach for this language.
At least you can do fast enumeration to shorten code a bit:
for (NSNumber *n in myArray) {
int num = [n intValue];
//do something....
}
EDIT:
The question has been asked 3 years ago. There have been new literals established to make it easier to create objects like NSNumbers or NSArrays:
NSNumber *n = #100;
or
NSArray *array = #[#100,#50,#10];
Nice short alternative for looping specific integers:
NSArray *numbers = [#"1000,237,2673" componentsSeparatedByString:#","];
for (NSString *i in numbers) {
[i intValue]; // Do something.
}
First start with a C array:
NSInteger myCArray = { 1000, 237, 2673 };
// calculate number of elements
NSUInteger myCArrayLength = sizeof(myCArray) / sizeof(NSInteger;
Second, if you need an NSArray loop through this array and create one:
NSMutableArray *myNSArray = [NSMutableArray arrayWithCapacity:myCArrayLength];
for(NSUInteger ix = 0; ix < myCArrayLength; ix++)
[myNSArray addObject:[NSNumber numberWithInteger:myCArray[ix]];
You can wrap the second piece of code up as a category on NSArray if you're doing it a lot.
too late. but u can do the following too.
int total = 0;
nsarray *myArray = #[#1.8,#100,#299.8];
for(nsnumber *num in myArray){
total+=num;
}

how to add int value from array to NSNumber?

Here is my code
I'm looping through the array and adding to the NSNumber.
NSNumber *totalValue = 0;
NSMutableArray *items = [10, 35, 25]; // Just for demo
for (int i=0; i < items.count; i++)
{
totalValue = totalValue + [items objectAtIndex:i] // How do I add the totalValue?
}
Can someone help me with this code?
NSNumber is an Objective-C class. Unlike in C++, operators cannot be overloaded in Objective-C so you have to call everything manually.
NSNumber *totalValue = [NSNumber numberWithInt:0];
for(…) {
totalValue = [NSNumber numberWithInt:[totalValue intValue] + [[items objectAtIndex:i] intValue]];
}
You might want to use NSInteger instead, which is faster (especially for a large number of items: memory allocation is expensive):
NSInteger totalValueInteger = 0; // no pointer, NSInteger is a POD!
for (…) {
totalValueInteger += [[items objectAtIndex:i] integerValue];
}
NSNumber *totalValue = [NSNumber numberWithInteger:totalValueInteger];
You should really only use NSNumber when you need an Objective-C object, like in an array, dictionary or coder. Otherwise, use a POD like NSInteger, int or double.
First of all, you can probably do this entire thing using KVC:
NSNumber *total = [items valueForKeyPath:#"#sum.integerValue"];
But to answer your original question, NSNumber is immutable which means you can't change it or increment its value. Creating a new NSNumber on each iteration of your loop is inefficient and wasteful.
You should use a standard int or NSInteger to sum up the total, and then convert the resulting value to an NSNumber at the end if you need it like that.
Might as well make the intermediate an int.
int temp = 0;
for(…) {
temp += [[items objectAtIndex:i] intValue];
}
NSNumber *totalValue = [NSNumber numberWithInt:temp];