Представьте себе вектор std: скажем, со 100 вещами на нем (от 0 до 99). Вы рассматриваете его как петлю. Итак, 105-й пункт - это индекс 4; вперед 7 из индекса 98 5.Осторожно удалять N элементов из «кругового» вектора (или, возможно, только NSMutableArray)
Вы хотите удалить N элементов после позиции индекса P.
Таким образом, удаление 5 пунктов после индекса 50; легко.
Или 5 предметов после индекса 99: когда вы удаляете 0 пять раз или от 4 до 0, отмечая, что позиция на 99 будет стерта от существования.
Худший, 5 предметов после индекса 97 - вам нужно иметь дело с обоими способами удаления.
Какой элегантный и прочный подход?
Вот скучный рутинный я написал
-(void)knotRemovalHelper:(NSMutableArray*)original
after:(NSInteger)nn howManyToDelete:(NSInteger)desired
{
#define ORCO ((NSInteger)[original count])
static NSInteger kount, howManyUntilLoop, howManyExtraAferLoop;
if (... our array is NOT a loop ...)
// trivial, if messy...
{
for (kount = 1; kount<=desired; ++kount )
{
if ((nn+1) >= ORCO)
return;
[original removeObjectAtIndex:(nn+1)];
}
return;
}
else // our array is a loop
// messy, confusing and inelegant. how to improve?
// here we go...
{
howManyUntilLoop = (ORCO-1) - nn;
if (howManyUntilLoop > desired)
{
for (kount = 1; kount<=desired; ++kount )
[original removeObjectAtIndex:(nn+1)];
return;
}
howManyExtraAferLoop = desired - howManyUntilLoop;
for (kount = 1; kount<=howManyUntilLoop; ++kount )
[original removeObjectAtIndex:(nn+1)];
for (kount = 1; kount<=howManyExtraAferLoop; ++kount)
[original removeObjectAtIndex:0];
return;
}
#undef ORCO
}
Update!
Второй ответ InVariant приводит к следующему превосходному решению. «Начиная с» намного лучше, чем «начиная с». Поэтому в рутине теперь используется «начать с». второй ответ Инвариантный приводит к этому очень простому решению ...
N раз делать, если P < currentsize удалить P еще удалить 0
-(void)removeLoopilyFrom:(NSMutableArray*)ra
startingWithThisOne:(NSInteger)removeThisOneFirst
howManyToDelete:(NSInteger)countToDelete
{
// exception if removeThisOneFirst > ra highestIndex
// exception if countToDelete is > ra size
// so easy thanks to Invariant:
for (do this countToDelete times)
{
if (removeThisOneFirst < [ra count])
[ra removeObjectAtIndex:removeThisOneFirst];
else
[ra removeObjectAtIndex:0];
}
}
обновления!
Toolbox указал отличную идею работы с новым массивом - супер KISS.
Только что заметил, что вам нужно N элементов * после * индекса P, но не включая P. В этом случае просто измените P на (P + 1)% ArraySize. –
Я согласен! Проще и приятнее! –