Индексные наборы: хранение индексов в массив

Вы используете индексные наборы для хранения индексов в некоторую другую структуру данных, такой как NSArray объект. Каждый индекс в индексном наборе может только появиться один раз, который является, почему индексные наборы не подходят для хранения произвольных наборов целых чисел. Поскольку индекс устанавливает (как на рисунке 1), используют диапазоны для хранения индексов, они обычно более эффективны, чем хранение набора целочисленных значений, такой как в массиве.

  Индексный набор рисунка 1 и взаимодействие массива

Индексируйте основные принципы набора

NSIndexSet объект управляет неизменным набором индексов — т.е. после создания индексного набора Вы не можете добавить индексы к нему или удалить индексы из него.

NSMutableIndexSet объект управляет непостоянным индексным набором, позволяющим дополнение и удаление индексов в любое время, автоматически выделяя память по мере необходимости.

Можно легко создать экземпляр одного типа индексного набора от другого использования инициализатора initWithIndexSet:. Это особенно полезно, если Вы хотите создать неизменный индексный набор, содержащий непересекающиеся наборы индексов, обычно создающихся с помощью непостоянных индексных наборов. Например, если Вы имеете NSMutableIndexSet объект называют myIndexes, которому добавили индексы к нему, можно создать неизменную копию следующим образом:

NSIndexSet *myImmutableIndexes=[[NSIndexSet alloc] initWithIndexSet: myIndexes];

Можно также инициализировать индексный набор от единственного индекса или диапазона индексов при помощи initWithIndex: или initWithIndexesInRange: метод.

Непостоянные индексные наборы

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

Если у Вас есть пустое NSMutableIndexSet объект называют myDisjointIndexes, можно заполнить его индексами: 1, 2, 5, 6, 7, и 10, как показано в Перечислении 1.

Перечисление 1  , Добавляющее индексы к непостоянному индексу, установлено

[myDisjointIndexes addIndexesInRange: NSMakeRange(1,2)];
[myDisjointIndexes addIndexesInRange: NSMakeRange(5,3)];
[myDisjointIndexes addIndex: 10];

Итерация через индексные наборы

Для доступа ко всем объектам, индексированным индексным набором, может быть удобно выполнить итерации последовательно через индексный набор. Итерация через индексный набор, а не через соответствующий массив, более эффективна, поскольку это позволяет Вам исследовать только индексы, которыми Вы интересуетесь. Если Вы имеете NSArray объект называют anArray и NSIndexSet объект называют anIndexSet, можно выполнить итерации вперед через индексный набор как показано в Перечислении 2.

Перечисление 2  Прямая итерация через индекс установлено

NSUInteger index=[anIndexSet firstIndex];
 
while(index != NSNotFound)
{
 
     NSLog(@" %@",[anArray objectAtIndex:index]);
     index=[anIndexSet indexGreaterThanIndex: index];
}

Например, когда Вы хотите выборочно удалить объекты из индексов от, иногда может быть необходимо выполнить итерации назад через индексный набор NSMutableArray объект. Можно выполнить итерации назад через индексный набор как показано в Перечислении 3.

  Итерация Реверса перечисления 3 через индекс установлена

NSUInteger index=[anIndexSet lastIndex];
 
while(index != NSNotFound)
{
 
     if([[aMutableArray objectAtIndex: index] isEqualToString:@"G"]){
          [aMutableArray removeObjectAtIndex:index];
     }
     index=[anIndexSet indexLessThanIndex: index];
}

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

Индексные наборы и блоки

Индексные наборы особенно мощны, когда используется в сочетании с блоками. Блоки позволяют Вам создавать индексные наборы, назначающие элементы массива, проходящие некоторый тест. Например, если у Вас есть несортированный массив чисел, и Вы хотите создать индексный набор, содержащий индексы ко всем числам меньше чем 20, Вы используете что-то подобное Перечислению 4.

Перечисление 4  , Создающее индексный набор из массива с помощью блока

NSIndexSet *lessThan20=[someArray indexesOfObjectsPassingTest:^(id obj, NSUInteger index, BOOL *stop){
     if ([obj isLessThan:[NSNumber numberWithInt:20]]){
          return YES;
     }
     return NO;
}];

Индексные наборы могут также использоваться в основанном на блоке перечислении массива. Для перечисления только индексов массива, содержавшегося в индексном наборе, используйте enumerateObjectsAtIndexes:options:usingBlock: метод.

Также индекс установил себя, может быть перечислен с помощью блока с enumerateIndexesUsingBlock: метод. Например, можно выполнить некоторую задачу для каждого объекта, индекс которого находится в наборе. Можно даже получить доступ к объектам от многократных массивов, если индексный набор допустим для используемых массивов, как в Перечислении 5.

Перечисление 5  , Перечисляющее индексный набор для доступа к многократным массивам

[anIndexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop){
     if([[firstArray objectAtIndex: idx] isEqual:[secondArray objectAtIndex: idx]]){
          NSLog(@"Objects at %i Equal",idx);
     }
}];