Inputted values from textfield to NSArray - ios

I have a problem creating a solution to this problem:
Create an app that will store 5 numbers (preferrably float) and then sort them out.The array type is immutable.
First off: My problem is how to get the floats from the textfield then put it into a array. My idea is to code it like this:
int a = [num1.text intValue];
int b = [num2.text intValue];
int c = [num3.text intValue];
NSArray *myArray;
myArray = [NSArray stringWithFormat: #"%f",a,b,c];
My second problem is that I can't understand how to sort the floats. Will you please give me some idea?
Thank you very much!

Something like this should work:
CGFloat a = [num1Label.text floatValue];
CGFloat b = [num2Label.text floatValue];
CGFloat c = [num3Label.text floatValue];
CGFloat d = [num4Label.text floatValue];
CGFloat e = [num5Label.text floatValue];
NSArray *array = #[ [NSNumber numberWithFloat:a],
[NSNumber numberWithFloat:b],
[NSNumber numberWithFloat:c],
[NSNumber numberWithFloat:d],
[NSNumber numberWithFloat:e]];
array = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
// logic for sorting
NSNumber *number1 = (NSNumber *)obj1;
NSNumber *number2 = (NSNumber*)obj2;
return [first compare:second];
}];
CGFloat is basically the same as float.
If you check the Documentation (OPTION + Click on that), you see this:
# define CGFLOAT_TYPE float
// ...
typedef CGFLOAT_TYPE CGFloat;
CG comes from Core Graphics.
float comes from C/C++
It is more recommended to use CGFloat in Objective-C, instead of simply float. Also, NSInteger instead of int.

Related

Array items showing error in IOS

I have an array with some items to rotate the image view when button is clicked, now when I pass the array with getting current index it showing an error, I'm confused why I'm getting this.
My code is this:
- (IBAction)my:(id)sender {
NSString *cureentIndex=0;
NSArray *persons = [NSArray arrayWithObjects:#"M_PI",#" M_PI_4",#" M_PI_2",#"M_PI*2", nil];
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
_imageView.transform = CGAffineTransformMakeRotation(person[cureentIndex])
if currentIndex != persons.count-1 {
currentIndex = currentIndex + 1
}else {
// reset the current index back to zero
currentIndex = 0
}
}
The error is here:
You have declared cureentIndex as NSString *, so when you say person[cureentIndex] the compiler thinks that person must be a dictionary, since you are using the [] access with an object. This causes the error since person is actually an array and it cannot be indexed with a string.
I think you meant to declare cureentIndex as int, or perhaps you meant to say currentIndex?
There are a lot of issues, please try this
NSInteger currentIndex = 0;
NSArray<NSNumber *> *persons = #[#(M_PI), #(M_PI_4), #(M_PI_2)];
- (IBAction)my:(id)sender {
_imageView.transform = CGAffineTransformMakeRotation(persons[currentIndex].doubleValue)
currentIndex = (currentIndex + 1) % persons.count;
}
There are some errors:
The index must be an int
NSString *cureentIndex=0;
becomes
int currentIndex = 0;
and the array must be of double not string, CGAffineTransformMakeRotation requires a CGFloat that is a double
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
becomes
NSArray *person = #[[NSNumber numberWithDouble:M_PI], [NSNumber numberWithDouble:M_PI_4], [NSNumber numberWithDouble:M_PI_2]];
and
_imageView.transform = CGAffineTransformMakeRotation(person[cureentIndex])
becomes
_imageView.transform = CGAffineTransformMakeRotation([person[cureentIndex] doubleValue]);
I don't know why you set currentIndex's property to NSString, In fact we always set the XXXindex(current/last/next) to int or NSInteger property.
Another, the person is an array, it's key must be an int!, it's
value could be any object.
I fix your code to this:
NSInteger currentIndex = 0;
NSArray *person = #[#"M_PI", #"M_PI_4", #"M_PI_2"];
CGFloat rotate = [person[currentIndex] floatValue];
_imageView.transform = CGAffineTransformMakeRotation(rotate);
you will find it did't work well, the ratate will be 0! Because, the NSString's method floatValue or doubleValue can only change string(like: #"123" #"0.5") to a number, the string(like: #"M_PI") can't be change to a right number.
I fix your code to this again:
NSInteger currentIndex = 0;
CGFloat mPi = M_PI;
NSArray *person = #[#(mPi), #(mPi / 4.0), #(mPi / 2.0)];
CGFloat rotate = [person[currentIndex] floatValue];
_imageView.transform = CGAffineTransformMakeRotation(rotate);
The Code works well! This is because M_PI is A Macro, if you
write code #"M_PI", the system can't recognize its value 3.1415926. So
your must write M_PI instead of #"M_PI".
In fact, this problem's core is you need a number, so your array must include some numbers! Or some string just like number! :)

Subtracting numbers as Objects - Objective C

I have a sorted array, yrs, which is what it sounds like (a sorted array of years). This array holds 5 objects and each is similar to the object below:
__NSCFNumber * (int)1995 0x79fa3200
I'm trying to subtract the last item from the first item to get the date range:
int first_year = [yrs objectAtIndex:0];
int last_year = [yrs objectAtIndex:4];
NSInteger numberOfCols = ([last_year intValue] - [first_year intValue] ) + 1;
The values of the items in the array are as follows:
first_year int 2078365328 2078365328 where it should be 1995
last_year int 2083083520 2083083520 where it should be
numberOfCols NSInteger 328 328
I honestly have no idea what's going on here.
EDIT
NSMutableArray * years = [NSMutableArray array];
NSMutableArray * atts = [NSMutableArray array];
for(Treatment * treatment in items)
{
NSLog(#"%#",treatment.treatmentMolecule);
NSNumber * startYr = [NSNumber numberWithInt:treatment.startDate.yr];
NSNumber * endYr = [NSNumber numberWithInt:treatment.endDate.yr];
if((![years containsObject:startYr]) && (![startYr isEqual:#0])){
[years addObject:startYr];
}
if((![years containsObject:endYr]) && (![endYr isEqual:#0])){
[years addObject:endYr];
}
}
for(Attack * att in arrayAttack)
{
NSNumber * startYr = [NSNumber numberWithInt:att.yr];
if(![years containsObject:startYr])
[years addObject:startYr];
}
//sort yrs
yrs = [years sortedArrayUsingComparator:(NSComparator)^(NSNumber * yr1, NSNumber * yr2){
return [yr1 compare:yr2];
}];
This is wrong:
int first_year = [yrs objectAtIndex:0];
The element in the array is an instance of NSNumber. Try to replace it with this:
NSNumber *first_year = [yrs objectAtIndex:0];
Even better, you can use firstObject and lastObject instead of hard codes indices.
I would write it like this:
NSNumber *first_year = [yrs firstObject];
NSNumber *last_year = [yrs lastObject];
NSInteger numberOfCols = ([last_year integerValue] - [first_year integerValue] ) + 1;
You should do
int first_year = [[yrs objectAtIndex:0] intValue];
int last_year = [[yrs objectAtIndex:4] intValue];
to get the integer values saved in NSNumber.

How to add array values in a string in ios

Can anybody please tell me how to put array values[Adding Values] into a string or integer.
Suppose an array a=[1,2,3].
After Adding(+ Action) it should be like
string=1+2+3=>6
Thanks and regards,
Use KVC Collection Operator
NSArray *array =#[#(1),#(2),#(3)];
NSLog(#"Sum is : %#", [array valueForKeyPath:#"#sum.self"]);
Simply loop over your string array and sum it up?!
NSArray *array = #[#"1", #"2", #"3"];
NSInteger sum = 0;
for (NSString *string in array) {
sum += [string integerValue];
}
NSLog(#"%ld", (long)sum);
NSArray *array = #[#1, #2, #3];
int sum = 0;
for (NSNumber * number in array)
{
sum += [number intValue];
}
NSString *result = [NSString stringWithFormat:#"%d", sum];
You can use KVC..
NSNumber *num1 = [NSNumber numberWithInt:1];
NSNumber *num2 = [NSNumber numberWithInt:2];
NSNumber *num3 = [NSNumber numberWithInt:3];
NSArray *arr1= #[num1, num2, num3];
NSString *str = [arr1 valueForKeyPath:#"#sum.intValue"];
NSLog(#"%#",str);
You can use:
NSArray *array = #[#1, #2, #3];
NSInteger sumArray = [[array valueForKeyPath:#"#sum.integerValue"] integerValue];
*I converted the final value to integer, if you don't need then you can replace it by:
NSString *sumArray = [array valueForKeyPath:#"#sum.integerValue"];
It's overkill to use NSArray.
Use plain C array.
int myArray[] = {1,2,3};
int i = 0; int sum= 0;
for (i=0; i < 3; i++){
sum += myArray[i];
}
char str[15];
sprintf(str, "%d", sum);
printf("%s", str);

Finding smallest and biggest value in NSArray of NSNumbers

What's an effective and great way to compare all the values of NSArray that contains NSNumbers from floats to find the biggest one and the smallest one?
Any ideas how to do this nice and quick in Objective-C?
If execution speed (not programming speed) is important, then an explicit loop is the fastest. I made the following tests with an array of 1000000 random numbers:
Version 1: sort the array:
NSArray *sorted1 = [numbers sortedArrayUsingSelector:#selector(compare:)];
// 1.585 seconds
Version 2: Key-value coding, using "doubleValue":
NSNumber *max=[numbers valueForKeyPath:#"#max.doubleValue"];
NSNumber *min=[numbers valueForKeyPath:#"#min.doubleValue"];
// 0.778 seconds
Version 3: Key-value coding, using "self":
NSNumber *max=[numbers valueForKeyPath:#"#max.self"];
NSNumber *min=[numbers valueForKeyPath:#"#min.self"];
// 0.390 seconds
Version 4: Explicit loop:
float xmax = -MAXFLOAT;
float xmin = MAXFLOAT;
for (NSNumber *num in numbers) {
float x = num.floatValue;
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
}
// 0.019 seconds
Version 5: Block enumeration:
__block float xmax = -MAXFLOAT;
__block float xmin = MAXFLOAT;
[numbers enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
float x = num.floatValue;
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
}];
// 0.024 seconds
The test program creates an array of 1000000 random numbers and then applies all sorting
techniques to the same array. The timings above are the output of one run, but I make about 20 runs with very similar results in each run. I also changed the order in which the 5 sorting methods are applied to exclude caching effects.
Update: I have now created a (hopefully) better test program. The full source code is here: https://gist.github.com/anonymous/5356982. The average times for sorting an
array of 1000000 random numbers are (in seconds, on an 3.1 GHz Core i5 iMac, release compile):
Sorting 1.404
KVO1 1.087
KVO2 0.367
Fast enum 0.017
Block enum 0.021
Update 2: As one can see, fast enumeration is faster than block enumeration (which is also stated here: http://blog.bignerdranch.com/2337-incremental-arrayification/).
EDIT: The following is completely wrong, because I forgot to initialize the object used as lock, as Hot Licks correctly noticed, so that no synchronization is done at all.
And with lock = [[NSObject alloc] init]; the concurrent enumeration is so slow
that I dare not to show the result. Perhaps a faster synchronization mechanism might
help ...)
This changes dramatically if you add the NSEnumerationConcurrent option to the
block enumeration:
__block float xmax = -MAXFLOAT;
__block float xmin = MAXFLOAT;
id lock;
[numbers enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
float x = num.floatValue;
#synchronized(lock) {
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
}
}];
The timing here is
Concurrent enum 0.009
so it is about twice as fast as fast enumeration. The result is probably not representative
because it depends on the number of threads available. But interesting anyway! Note that I
have used the "easiest-to-use" synchronization method, which might not be the fastest.
Save float by wrapping under NSNumber then
NSNumber *max=[numberArray valueForKeyPath:#"#max.doubleValue"];
NSNumber *min=[numberArray valueForKeyPath:#"#min.doubleValue"];
*Not compiled and checked, already checked with intValue, not sure about double or float
sort it. take the first and the last element.
btw: you cant store floats in an NSArray, you will need to wrap them in NSNumber objects.
NSArray *numbers = #[#2.1, #8.1, #5.0, #.3];
numbers = [numbers sortedArrayUsingSelector:#selector(compare:)];
float min = [numbers[0] floatValue];
float max = [[numbers lastObject] floatValue];
I agree with sorting the array then picking the first and last elements, but I find this solution more elegant (this will also work for non numeric objects by changing the comparison inside the block):
NSArray *unsortedArray = #[#(3), #(5), #(1)];
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSNumber *item1 = (NSNumber *)obj1;
NSNumber *item2 = (NSNumber *)obj2;
return [item1 compare:item2];
}];
If you really want to get fancy and have a really long list and you don't want to block your main thread, this should work:
NSComparator comparison = ^NSComparisonResult(id obj1, id obj2) {
NSNumber *item1 = (NSNumber *)obj1;
NSNumber *item2 = (NSNumber *)obj2;
return [item1 compare:item2];
};
void(^asychSort)(void) = ^
{
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:comparison];
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(#"Finished Sorting");
//do your callback here
});
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), asychSort);
Made simple
NSArray *numbers = #[#2.1, #8.1, #5.0, #.3];
numbers = [numbers sortedArrayUsingSelector:#selector(compare:)];
float min = [numbers[0] floatValue];
float max = [[numbers lastObject] floatValue];
NSLog(#"MIN%f",min);
NSLog(#"MAX%f",max);

how to round off NSNumber and create a series of number in Object C

May i know how to round up a NSNumber in object C ?
for(int i=6; i>=0; i--)
{
DayOfDrinks *drinksOnDay = [appDelegate.drinksOnDayArray objectAtIndex:i];
NSString * dayString= [NSDate stringForDisplayFromDateForChart:drinksOnDay.dateConsumed];
[dayArray addObject:dayString];//X label for graph the day of drink.
drinksOnDay.isDetailViewHydrated = NO;
[drinksOnDay hydrateDetailViewData];
NSNumber *sdNumber = drinksOnDay.standardDrinks;
[sdArray addObject: sdNumber];
}
inside this sdArray are all the numbers like this 2.1, 1.3, 4.7, 3.1, 4.8, 15.1, 7.2;
i need to plot a graph Y axis so i need a string of whatever is from the NSNumber to show
a NSString of this {#"0", #"2", #"4", #"6", #"8", #"10", #"12",#"14",#"16"}. as i need to start from zero, i need to determine which is the biggest number value. in this case it will be 15.1 to show 16 in the graph. instead of doing a static labeling, i will like to do a dynamic labeling.
what you have seen in the graph is static numbering not dynamic.
i'm sorry for missing out the important info.
thanks for all the comments
Check out the math functions in math.h, there's some nice stuff there like
extern double round ( double );
extern float roundf ( float );
As for the rest of your question you probably have to parse your strings into numbers, perform whatever action you want on them (rounding, sorting, etc) then put them back into strings.
Your edit now makes a lot more sense. Here is an example of getting all even numbers from your 0 to your max value in your NSArray of NSNumbers (assuming all values are positive, could be changed to support negative values by finding minimum float value as well).
NSArray *sdArray = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:2.1],
[NSNumber numberWithFloat:1.3],
[NSNumber numberWithFloat:4.7],
[NSNumber numberWithFloat:3.1],
[NSNumber numberWithFloat:4.8],
[NSNumber numberWithFloat:15.1],
[NSNumber numberWithFloat:7.2],
nil];
//Get max value using KVC
float fmax = [[sdArray valueForKeyPath:#"#max.floatValue"] floatValue];
//Ceiling the max value
int imax = (int)ceilf(fmax);
//Odd check to make even by checking right most bit
imax = (imax & 0x1) ? imax + 1 : imax;
NSMutableArray *array = [NSMutableArray arrayWithCapacity:(imax / 2) + 1];
//Assuming all numbers are positive
//(should probably just use unsigned int for imax and i)
for(int i = 0; i <= imax; i +=2)
{
[array addObject:[NSString stringWithFormat:#"%d", i]];
}
NSLog(#"%#", array);

Resources