Question

I want to get the maximum and minimum values of a NSMutableArray so I can create a core-plot plotspace and graph based around those max and min values.

My code is as follows:

NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:100];
NSUInteger i;
for (i=0; i<60; i++){
id x = [NSNumber numberWithFloat:i*0.05];
id y = [NSNumber numberWithFloat:1.2*rand()/(float)RAND_Max + 0.6];
[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]];
}

self.dataForPlot = contentArray;

CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat() length:CPDecimalFromFloat()];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat() length:CPDecimalFromFloat()];

What do I fill in the blanks for xRange and yRange assignment if I want the graph to span only the space of what's specified in contentArray?

No correct solution

OTHER TIPS

In this case, you should use -[CPPlotSpace scaleToFitPlots:]. For more general calculations on array values, read on...

This is an ideal use for Key-Value coding and associated array operators. In your example,

float maxX = [[contentArray valueForKeyPath:@"@max.x"] floatValue];
float minY = [[contentArray valueForKeyPath:@"@min.x"] floatValue];

float maxY = [[contentArray valueForKeyPath:@"@max.y"] floatValue];
float minY = [[contentArray valueForKeyPath:@"@min.y"] floatValue];

The array operators call valueForKeyPath: on the contentArray which gives an array built by calling the same valueForKeyPath: on each member of the array with the key path to the right of the array operator (i.e. @min and @max). The orignal call then applies the given operator to the resulting array. You could easily define a category on NSArray to give you back a struct of min/max values:

typedef struct {
  float minX; 
  float minY;
  float maxX;
  float maxY;
} ArrayValueSpace;

@implementation NSArray (PlotSpaceAdditions)
- (ArrayValueSpace)psa_arrayValueSpace {
  ArrayValueSpace result;

  result.maxX = [[contentArray valueForKeyPath:@"@max.x"] floatValue];
  result.minX = [[contentArray valueForKeyPath:@"@min.x"] floatValue];

  result.maxY = [[contentArray valueForKeyPath:@"@max.y"] floatValue];
  result.minY = [[contentArray valueForKeyPath:@"@min.y"] floatValue];

  return result;
}

You can find max and min values when you fill it, but it would work just when used in your snippet. If you want something more generic you should simply go through the list and searching for it.

// contentArray already defined
int maxX = 0, minX = 1000, maxY = 0, minY = 1000;

for (int i = 0; i < [contentArray count]; ++1)
{
   int curX = [[[contentArray objectForKey:@"x"] objectAtIndex:i] integerValue];
   int curY = [[[contentArray objectForKey:@"y"] objectAtIndex:i] integerValue];

   if (curX < minX)
     minX = curX;
   else if (curX > maxX)
     maxX = curX;

   if (curY < minY)
     minY = curY;
   else if (curY > maxY)
     maxY = curY;
}

You could use fast enumeration through the array. .

NSUInteger  maxX = 0;
NSUInteger  minX = 0xFFFFFFFF; //(for 32 bit)
NSUInteger  maxY = 0;
NSUInteger  minY = 0xFFFFFFFF; //(for 32 bit)
for ( NSDictionary *dict in contentArray ) 
{
    NSUInteger   newX = [[dict objectForKey:@"x"] integerValue];
    NSUInteger   newY = [[dict objectForKey:@"y"] integerValue];


    if (maxX > newX) maxX = newX;
    if (minX > newX) minX = newX;
    if (maxY > newY) maxY = newY;
    if (minY > newY) minX = newY;
}

if you have NSMutableArray of NSDictionary objects you can use this:

-(float)findMax:array arrayKey:obj {
    float max = [[[array objectAtIndex:0] objectForKey:obj] floatValue];
    for ( NSDictionary *dict in array ) {
        if(max<[[dict objectForKey:obj] floatValue])max=[[dict objectForKey:obj] floatValue];
    }
    return max;
}

-(float)findMin:array arrayKey:obj {
    float min = [[[array objectAtIndex:0] objectForKey:obj] floatValue];
    for ( NSDictionary *dict in array ) {
        if (min > [[dict objectForKey:obj] floatValue])min = [[dict objectForKey:obj] floatValue];
    }
    return min;
}

You would access methods like this if in another class:

GraphData *c=[[GraphData alloc] init];
float maxY=[c findMax:plotData arrayKey:[NSNumber numberWithInt:1]]; //1 or 0 depending on axis 
[c release];

//This gives Max and Min Value in NSMutableArrray -(void)FindingMinAndMaxValueInNSMutableArray{

NSMutableArray *array=[[NSMutableArray 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];

NSLog(@"The Array Value is %@",array);
NSLog(@"The Array Count is %lu",(unsigned long)array.count);

NSNumber *maxValue = [array valueForKeyPath:@"@max.doubleValue"];
NSLog(@"The maxValue is %@",maxValue);
NSString *str=[NSString stringWithFormat:@"%@",maxValue];
NSInteger path=[array indexOfObject:str];
NSIndexPath *indexpath=[NSIndexPath indexPathForItem:path inSection:0];
NSLog(@"Max Value = %@ and index = %ld",maxValue,(long)indexpath.row);


NSNumber *minValue = [array valueForKeyPath:@"@min.doubleValue"];
NSLog(@"The minValue is %@",minValue);
NSString *str1 = [NSString stringWithFormat:@"%@",minValue];
NSInteger path1 = [array indexOfObject:str1];
NSIndexPath *indexPath1 = [NSIndexPath indexPathForItem:path1 inSection:0];
NSLog(@"Min Value =%@ and index = %ld",minValue,(long)indexPath1.row);

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow