Объект-C: Получение минимума/максимального значения в NSMutableArray

Я хочу получить максимальные и минимальные значения NSMutableArray, таким образом, я могу создать базовый график plotspace и график, базирующийся вокруг тех макс. значений и минимальных значений.

Мой код следующие:

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

Что я восполняю пробелы для xRange и yRange присвоения, если я хочу, чтобы график охватил только пространство того, что определяется в contentArray?

10
задан Kevin 26 February 2010 в 19:17
поделиться

3 ответа

В этом случае вы должны использовать - [CPPlotSpace scaleToFitPlots:] . Для более общих вычислений значений массива прочтите ...

Это идеальное использование для кодирования значения ключа и связанных операторов массива . В вашем примере

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

операторы массива вызывают valueForKeyPath: в contentArray , который дает массив, построенный путем вызова одного и того же valueForKeyPath: для каждого члена массив с ключевым путем справа от оператора массива (т.е. @min и @max ). Затем исходный вызов применяет данный оператор к результирующему массиву. Вы можете легко определить категорию в NSArray , чтобы получить структуру минимальных / максимальных значений:

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;
}
21
ответ дан 3 December 2019 в 18:33
поделиться

Можно использовать Win32 API IsWindow .

Не рекомендуется использовать его, хотя по 2 причинам:

  1. дескрипторы Windows могут быть повторно использованы после того, как окно будет уничтожено, поэтому вы не знаете, есть ли у вас дескриптор для совершенно другого окна или нет.
  2. Состояние может измениться непосредственно после этого вызова, и вы будете думать, что оно действительно, но может быть действительно недействительным.

От MSDN (той же линии связи, что и выше):

Поток не должен использовать IsWindow для окно, которое оно не создало, потому что окно может быть разрушено после эта функция была вызвана. Далее, потому что дескрипторы окон повторно используются дескриптор может даже указывать на другое окно.

Что можно сделать?

Возможно, вашу проблему можно перестроить таким образом, чтобы у вас не было необходимости проверять действительный дескриптор. Может быть, например, можно установить канал от клиента к серверу.

Вы также можете создать крючок окна для обнаружения появления определенных сообщений, но это, вероятно, избыточно для большинства потребностей.

-121--1707045-

Фактически это Guid . Все типы создаются с использованием ключевого слова new . Ссылочные типы из типов значений можно определить по тому, являются ли они классом , интерфейсом или делегатом (все ссылочные типы), или структурой или перечислением (типы значений).

-121--1320486-

Можно найти максимальное и минимальное значения при его заполнении, но оно будет работать только при использовании в фрагменте. Если вы хотите что-то более общее, вы должны просто пройти через список и искать его.

// 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
ответ дан 3 December 2019 в 18:33
поделиться

Вы можете использовать быстрое перечисление по массиву. .

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
ответ дан 3 December 2019 в 18:33
поделиться