Цикл с использованием NSRange - PullRequest
6 голосов
/ 30 ноября 2011

Я пытаюсь использовать NSRange для хранения диапазона лет, например

NSRange years = NSMakeRange(2011, 5);

Я знаю, NSRange используется в основном для фильтрации, однако я хочу перебрать элементы в диапазоне. Возможно ли это без преобразования NSRange в NSArray?

Ответы [ 4 ]

8 голосов
/ 30 ноября 2011

Звучит так, будто вы ожидаете, что NSRange будет похож на объект Python range. Это не; NSRange это просто структура

typedef struct _NSRange {
       NSUInteger location;
       NSUInteger length;
} NSRange;

не объект. Создав его, вы можете использовать его члены в простом старом цикле for:

NSUInteger year;
for(year = years.location; year < NSMaxRange(years); year++ ){
    // Do your thing.
}

(Продолжая работать в предположении, что вы думаете о Python.) В ObjC есть синтаксис, называемый fast enumeration для перебора содержимого NSArray, который приятно похож на Python for цикл, но поскольку буквенные и примитивные числа не могут быть помещены в NSArray, вы не можете напрямую перейти от NSRange к массиву Какао.

Категория может сделать это проще, хотя:

@implementation NSArray (WSSRangeArray)

+ (id)WSSArrayWithNumbersInRange:(NSRange)range
{
    NSMutableArray * arr = [NSMutableArray array];
    NSUInteger i;
    for( i = range.location; i < NSMaxRange(range); i++ ){
        [arr addObject:[NSNumber numberWithUnsignedInteger:i]];
    }

    return arr;
}

Затем вы можете создать массив и использовать быстрое перечисление:

NSArray * years = [NSArray WSSArrayWithNumbersInRange:NSMakeRange(2011, 5)];
for( NSNumber * yearNum in years ){
    NSUInteger year = [yearNum unsignedIntegerValue];
    // and so on...
}
6 голосов
/ 30 ноября 2011

Помните, что NSRange - это структура, содержащая два целых числа, представляющих начало и длину диапазона. Вы можете легко перебрать все содержащиеся в нем целые числа, используя цикл for.

NSRange years = NSMakeRange(2011, 5);
NSUInteger year;
for(year = years.location; year < years.location + years.length; ++year) {
    // Use the year variable here
}
3 голосов
/ 01 июля 2013

Это немного старый вопрос, но альтернативой использованию NSArray было бы создание NSIndexSet с желаемым диапазоном (используя indexWithIndexesInRange: или initWithIndexesInRange:), а затем использование перечисления блоков, как вhttps://stackoverflow.com/a/4209289/138772. (казалось уместным, так как я сам проверял это.)

0 голосов
/ 25 августа 2014

Мое альтернативное решение для этого состояло в том, чтобы определить макрос только для того, чтобы сделать сокращение быстрее.

#define NSRangeEnumerate(i, range)    for(i = range.location; i < NSMaxRange(range); ++i)

Чтобы позвонить, вы делаете:

NSArray *array = @[]; // must contain at least the following range...
NSRange range = NSMakeRange(2011, 5);
NSUInteger i;
NSRangeEnumerate(i, range) {
    id item = array[i];
    // do your thing
}

лично я все еще пытаюсь понять, как я могу написать макрос, чтобы я мог просто назвать его как:

NSRangeEnumerate(NSUInteger i, range) {

}

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

...