3

I have a simple looking piece of code that has me completely flummoxed.

NSInteger ymax;
NSInteger ymin; 
NSInteger numberIndex1;
NSInteger numberIndex2;


for (NSNumber *theNumber in array2)
{
    if ([theNumber integerValue] > ymax) {
        ymax = [theNumber integerValue];
        numberIndex1 = [array2 indexOfObject:theNumber];
    }
}

for (NSNumber *theNumber in array2)
{
    if ([theNumber integerValue] < ymin) {
        ymin = [theNumber integerValue];
        numberIndex2 = [array2 indexOfObject:theNumber];
    }

} 

NSLog(@"Highest number: %d at index: %d", ymax, numberIndex1);
NSLog(@"Lowest number: %d at index: %d", ymin, numberIndex2);

The NSLog is outputted as:

Highest number: 129171656 at index: -1073752392 (Huh??)

Lowest number: 57 at index: 5 (Correct)

How do you explain this odd behaviour? Both the functions look the same. One is working and one isn't? I've played around a lot with this, but I still can't put my finger on it. Any help would be appreciated/

geekchic
  • 2,371
  • 4
  • 29
  • 41

5 Answers5

2

You can get maximum and minimum number as below code. It may help you

NSNumber * max = [array2 valueForKeyPath:@"@max.intValue"];
NSNumber * min = [array2 valueForKeyPath:@"@min.intValue"];
NSUInteger numberIndex1 = [array indexOfObject:min];
NSUInteger numberIndex2 = [array indexOfObject:max];

NSLog(@"Max Value = %d and index = %d",[max intValue],numberIndex1);
NSLog(@"Min Value = %d and index = %d",[min intValue],numberIndex2);
Rahul Patel
  • 5,858
  • 6
  • 46
  • 72
  • 1
    `indexOfObject:` requires an object and not a float/int or any other basic data type. – Amresh Kumar Aug 07 '13 at 07:19
  • @RahulPatel Since you're using `.intValue` in `valueForKeyPath:`, the logic will break if the actual value of the `NSNumber` goes beyond the scope of an integer. – Amresh Kumar Aug 07 '13 at 07:32
  • @AmreshKumar you are right. This is why I didn't go for this method in the first place. My code was longer, but worked better for me. – geekchic Aug 07 '13 at 07:33
  • 1
    @AmreshKumar : you are right bur questioner has not define which are the values that's why i mentioned code only for idea. not for copy paste – Rahul Patel Aug 07 '13 at 07:35
1

Please initialize NSInteger ymax = 0; NSInteger ymin = 0 ; NSInteger numberIndex1 = 0; NSInteger numberIndex2 = 0; It will fix your issue. Otherwise it is checking with a garbage value and giving wrong result.

kumar123
  • 791
  • 7
  • 21
  • This fixes my problem of getting the max value. But now the min is botched up. Highest number: 491 at index: 2 Lowest number: 0 at index: 0 But I think initializing like so `NSInteger ymin = [array2 indexOfObject:0];` should fix that. – geekchic Aug 07 '13 at 07:26
  • @nikhitadkslfslg yes.In max case also you can do. – kumar123 Aug 07 '13 at 07:30
1

If I am not wrong you are considering the default value of NSInteger is 0, No, it isn't guaranteed to be zero, since it's a local automatic variable. Without initialization, its value is indeterminate.

so you need to set default values for your var, start with ymax = -1;

Tarek Hallak
  • 18,422
  • 7
  • 59
  • 68
  • You're right, that was the issue. However in this case, ymax = 0; worked fine, but ymin needed the be initialized with the first element of the array or it returned null/ – geekchic Aug 07 '13 at 07:30
  • No not necessarily, set ymin = NSIntegerMax; – Tarek Hallak Aug 07 '13 at 07:33
  • I wasn't aware of that. Works great too, thanks. [This](http://stackoverflow.com/questions/4800015/what-is-the-maximum-value-of-nsinteger) helped. – geekchic Aug 07 '13 at 07:37
1

enjoy with my answer.......happy coding

NSArray *arr1=[[NSArray alloc]initWithObjects:@"0.987",@"0.951",@"0.881",@"0.784",@"0.662",@"0.522",@"0.381",@"-0.265",@"-0.197", @"0.189",@"-0.233",@"0.310",@"0.402",@"0.402",@"0.988",@"0.633",@"0.661",@"0.656",@"0.617",@"0.634",@"0.690",@"0.767",@"0.836",nil];

NSNumber * max = [arr1 valueForKeyPath:@"@max.floatValue"];
NSString *str=[NSString stringWithFormat:@"%@",max];
NSInteger path=[arr1 indexOfObject:str];
NSIndexPath *indepath=[NSIndexPath indexPathForItem:path inSection:0];

NSNumber * min = [arr1 valueForKeyPath:@"@min.floatValue"];
 NSString *str1=[NSString stringWithFormat:@"%@",min];
NSInteger path1=[arr1 indexOfObject:str1];
NSIndexPath *indepath1=[NSIndexPath indexPathForItem:path1 inSection:0];


NSLog(@"Max Value = %f and index = %ld",[max floatValue],(long)indepath.row);
NSLog(@"Min Value = %f and index = %ld",[min floatValue],(long)indepath1.row);
rams
  • 49
  • 1
  • 2
  • 9
-3

A more legitimate solution would be:


NSArray *originalArray = @[[NSNumber numberWithInt:91],
                               [NSNumber numberWithInt:12],
                               [NSNumber numberWithInt:99123],
                               [NSNumber numberWithInt:9],
                               [NSNumber numberWithInt:43234]];
NSArray *sortedArray = [originalArray sortedArrayUsingSelector:@selector(compare:)];
NSNumber *minNumber = [sortedArray objectAtIndex:0];
NSNumber *maxNumber = [sortedArray lastObject];
NSInteger minIndex = [originalArray indexOfObject:minNumber];
NSInteger maxIndex = [originalArray indexOfObject:maxNumber];
Amresh Kumar
  • 1,445
  • 17
  • 30
  • 1
    Remark: For a large array, sorting it just to find the minimum and maximum value is *slower* than enumerating the array or Key-Value Coding methods, compare http://stackoverflow.com/a/15931719/1187415. – Martin R Aug 07 '13 at 07:33