2010-02-26 9 views
10

Quiero obtener los valores máximo y mínimo de un NSMutableArray para poder crear un plotspace y un gráfico de núcleo basado en esos valores máximo y mínimo.OBJ-C: obteniendo el valor mínimo/máximo en un NSMutableArray

Mi código es el siguiente:

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()]; 

Lo que tengo que llenar los espacios en blanco para xrange y yrange asignación si quiero el gráfico para abarcar sólo el espacio de lo que está especificado en contentArray?

Respuesta

0

Puede encontrar valores máximos y mínimos cuando lo rellena, pero funcionaría solo cuando se utiliza en su fragmento. Si desea algo más genérico, simplemente debe ir a la lista y buscarla.

// 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; 
} 
0

Puede usar la enumeración rápida a través de la matriz. .

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; 
} 
+0

no sé a ciencia cierta que esto es más rápido, pero para el trabajo final podría usar: maxX = MAX (maxX, newX); etc ... –

21

En este caso, debe usar -[CPPlotSpace scaleToFitPlots:]. Para obtener más información sobre los valores de matriz, siga leyendo ...

Este es un uso ideal para la codificación de clave-valor y array operators asociado. En su ejemplo,

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]; 

Los operadores de matriz llaman valueForKeyPath: en el contentArray lo que da una matriz generada mediante una llamada al mismo valueForKeyPath: en cada miembro de la matriz con la ruta de la clave a la derecha del operador array (es decir @min y @max). La llamada original aplica el operador dado a la matriz resultante. Se podría definir fácilmente una categoría en NSArray para dar vuelta una estructura de valores mín/máx:

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; 
} 
+0

Gracias Barry, tu respuesta fue muy útil. ¿Sabes si también hay una función de ajuste automático para ejes? – Kevin

+0

La clase 'CPAxis' admite una política de etiquetado automático (' CPAxisLabelingPolicyAutomatic'). Creo que el eje abarcará automáticamente el espacio de la trama, por lo que solo tendrá que establecer la política de etiquetado en automático y luego decirle que vuelva a etiquetar cuando el espacio de la gráfica cambie de tamaño. –

+0

@BarryWark ¿Qué sucede si tengo 2 o más matrices diferentes para trazar en la misma área de gráfico? ¿Cómo puedo tomar el valor Y más pequeño y más grande de todas las matrices? –

0

si tiene NSMutableArray de NSDictionary objetos que se pueden utilizar esto:

-(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; 
} 

Se podría acceder a los métodos así si en otra clase:

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