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

Cocoa

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

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

Cocoa NSIndexSet

Основы Индекс наборов

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

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

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

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

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

Изменяемые индекс наборы

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

  • addIndex: добавляет индекс
  • addIndexesInRange: добавляет индексы в диапазоне
  • removeIndex: удаляет индекс
  • removeIndexesInRange: удаляет индексы в диапазоне

Если у вас есть пустой 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);
   }
}];
 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac