如何在NSMutableArray上移动项目?

时间:2011-10-17 20:19:20

标签: objective-c

我想将一个字符串项移到列表的顶部。

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

如何将狗移到列表顶部?

3 个答案:

答案 0 :(得分:13)

您将删除该项目并将其插入正确的空格:

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;
    }
}

此方法将覆盖您的所有列表并搜索“dog”,如果发现它将从原始列表中删除它并将其移至索引0。

答案 1 :(得分:6)

我想指出你的方法效率低下。通过从NSMutableArray中删除/插入对象,可能会影响删除/插入后的每一行。我说'可能',因为不清楚Apple使用哪种内部方法来维护它们的可变数组。但是,假设它是一个简单的c-array,那么删除/插入索引之后的每一行都需要向下/向上移动。在一个非常大的数组中,如果移动的项目在开头,这可能是低效的。但是,替换数组中的项目根本不是低效的。因此以下是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);
        }
    }
}

答案 2 :(得分:3)

您可以删除现有元素,例如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];
}