Как переместить элемент на NSMutableArray? - PullRequest
5 голосов
/ 18 октября 2011

Я хочу переместить строковый элемент в начало списка.

NSMutableArray animal = "cat", "lion", "dog", "tiger";

Как переместить собаку в начало списка?

Ответы [ 3 ]

13 голосов
/ 18 октября 2011

Вы удалили бы элемент и вставили бы его в правильном месте:

id tmp=[[animals objectAtIndex:2] retain];
[animals removeObjectAtIndex:2];
[animals insertObject:tmp atIndex:0];
[tmp release];

Вы должны сохранить объект или когда вы скажете массиву удалить его, он освободит объект.

Если вы не знаете индекс, вы могли бы сделать что-то вроде этого:

NSMutableArray* animals = [NSMutableArray arrayWithObjects:@"cat", @"lion", @"dog", @"tiger",nil];

for (NSString* obj in [[animals copy] autorelease]) {
    if ([obj isEqualToString:@"dog"]) {
        NSString* tmp = [obj retain];
        [animals removeObject:tmp];
        [animals insertObject:tmp atIndex:0];
        break;
    }
}

Этот метод будет проходить по всему вашему списку и искать «собака», а если он найдет, он удалит его изисходный список и переместить его в индекс 0.

6 голосов
/ 22 февраля 2012

Я хотел бы указать на неэффективность вашего метода.Удаляя / вставляя объект из NSMutableArray, вы потенциально влияете на каждую строку после удаления / вставки.Я говорю «потенциально», потому что не ясно, какой внутренний метод Apple использует для поддержки своих изменяемых массивов.Однако, если предположить, что это простой c-массив, то каждую строку после этого индекса удаления / вставки нужно будет перемещать вниз / вверх.В очень большом массиве это может быть неэффективно, если перемещаемые элементы находятся в начале.Однако замена элементов в массиве вовсе не является неэффективной.Таким образом, следующая категория для NSMutableArray (обратите внимание, что этот код находится в ARC, поэтому нет управления памятью):

- (void) moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex{
    if (fromIndex == toIndex) return;
    if (fromIndex >= self.count) return; //there is no object to move, return
    if (toIndex >= self.count) toIndex = self.count - 1; //toIndex too large, assume a move to end
    id movingObject = [self objectAtIndex:fromIndex];

    if (fromIndex < toIndex){
        for (int i = fromIndex; i <= toIndex; i++){
            [self replaceObjectAtIndex:i withObject:(i == toIndex) ? movingObject : [self objectAtIndex:i + 1]];
        }
    } else {
        id cObject;
        id prevObject;
        for (int i = toIndex; i <= fromIndex; i++){
            cObject = [self objectAtIndex:i];
            [self replaceObjectAtIndex:i withObject:(i == toIndex) ? movingObject : prevObject];
            prevObject = cObject;
        }
    }
}

Кроме того, небольшой бонус для дальнейшего расширения функциональности, если вы выполняете операции над элементамипереехал (например, обновление БД или что-то), следующий код был очень полезным для меня:

- (void) moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex withBlock:(void (^)(id, NSUInteger))block{
    if (fromIndex == toIndex) return;
    if (fromIndex >= self.count) return; //there is no object to move, return
    if (toIndex >= self.count) toIndex = self.count - 1; //toIndex too large, assume a move to end
    id movingObject = [self objectAtIndex:fromIndex];
    id replacementObject;

    if (fromIndex < toIndex){
        for (int i = fromIndex; i <= toIndex; i++){
            replacementObject = (i == toIndex) ? movingObject : [self objectAtIndex:i + 1];
            [self replaceObjectAtIndex:i withObject:replacementObject];
            if (block) block(replacementObject, i);
        }
    } else {
        id cObject;
        id prevObject;
        for (int i = toIndex; i <= fromIndex; i++){
            cObject = [self objectAtIndex:i];
            replacementObject = (i == toIndex) ? movingObject : prevObject;
            [self replaceObjectAtIndex:i withObject:replacementObject];
            prevObject = cObject;
            if (block) block(replacementObject, i);
        }
    }
}
3 голосов
/ 18 октября 2011

Вы можете удалить существующий элемент, например, dog, а затем снова вставить его в начало массива.

NSMutableArray *animals = [NSMutableArray arrayWithObjects:@"cat", @"lion", @"dog", @"tiger",nil];
NSString *dog = @"dog";
// Check to see if dog is in animals
if ( [animals containsObject:dog] ) {
  // Remove dog from animals and reinsert
  // at the beginning of animals
  [animals removeObject:dog];
  [animals insertObject:dog atIndex:0];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...