NSMutablearray将对象从索引移到索引


Answers:


119
id object = [[[self.array objectAtIndex:index] retain] autorelease];
[self.array removeObjectAtIndex:index];
[self.array insertObject:object atIndex:newIndex];

就这样。注意保留计数很重要,因为数组可能是引用对象的唯一数组。


当您保持指向事物的指针时,没有太多理由要自动释放,是吗?而不是在移除之前保留并在插入之后释放。
Sixten Otto 2010年

是的,这是真的。只是减少了一行代码,但是我确实理解您的观点,直接发布它会更便宜。我并不介意一个对象,但是您最好在一个(紧)循环中避免这种情况。
Joost 2010年

3
为什么不使用-(void)exchangeObjectAtIndex:(NSUInteger)idx1和ObjectAtIndex:(NSUInteger)idx2;
莎伦·英登

4
@SarenInden因为该方法交换指定的对象,所以请勿将单个对象移到其他位置。
Joost 2014年

50

符合ARC的类别:

NSMutableArray + Convenience.h

@interface NSMutableArray (Convenience)

- (void)moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;

@end

NSMutableArray + Convenience.m

@implementation NSMutableArray (Convenience)

- (void)moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex
{
    // Optional toIndex adjustment if you think toIndex refers to the position in the array before the move (as per Richard's comment)
    if (fromIndex < toIndex) {
        toIndex--; // Optional 
    }

    id object = [self objectAtIndex:fromIndex];
    [self removeObjectAtIndex:fromIndex];
    [self insertObject:object atIndex:toIndex];
}

@end

用法:

[mutableArray moveObjectAtIndex:2 toIndex:5];

6
toIndex如果您的身高fromIndex小于您的身高,最好减一减toIndex
理查德

2
如果您指定的toIndex指向移动之前数组中的位置,则Richard的点是有效的。如果这是您的期望,那么您可能应该按照建议减少toIndex。但是,如果指定的toIndex引用了它在数组中的最终位置,则不应减少。
奥利弗·皮尔曼

2
@OliverPearmain抱歉,我正在努力掌握这个想法。[A,B,C]调用后,使用您的方法(建议减少量)使用数组moveObjectAtIndex:0 toIndex:1会导致[A,B,C]。那合乎逻辑吗?
斯图尔特

1
remove有效地减少之后所有对象的索引fromIndex
理查德

13

使用Swift Array,就像这样简单:

迅捷3

extension Array {
    mutating func move(at oldIndex: Int, to newIndex: Int) {
        self.insert(self.remove(at: oldIndex), at: newIndex)
    }
}

迅捷2

extension Array {
    mutating func moveItem(fromIndex oldIndex: Index, toIndex newIndex: Index) {
        insert(removeAtIndex(oldIndex), atIndex: newIndex)
    }
}

2

如果有NSArray,则不能移动或重新排列任何东西,因为它是不可变的。

您需要一个NSMutableArray。这样,您可以添加和替换对象,这当然也意味着您可以对数组重新排序。


0

你不能 NSArray是一成不变的。您可以将该阵列复制到中NSMutableArray(或首先使用该阵列)。可变版本具有移动和交换其项目的方法。


抱歉,我的意思是可变的,但是nsmutablearray没有移动方法。
乔纳森。

5
当然可以。尝试-exchangeObjectAtIndex:withObjectAtIndex:。此外,还有各种分类方法。
Sixten Otto 2010年

2
没有切换2个对象,我想移动1
乔纳森。

正如其他张贴者所指出的,您需要删除并重新添加。
Sixten Otto 2010年

0

我想如果我理解正确,您可以执行以下操作:

- (void) tableView: (UITableView*) tableView moveRowAtIndexPath: (NSIndexPath*)fromIndexPath toIndexPath: (NSIndexPath*) toIndexPath

{
    [self.yourMutableArray moveRowAtIndex: fromIndexPath.row toIndex: toIndexPath.row]; 
    //category method on NSMutableArray to handle the move
}

然后,您可以使用– insertObject:atIndex:方法向NSMutableArray添加类别方法来处理移动。


是的,我正在尝试查找要实现的category方法的代码,应该将其插入然后删除吗?
乔纳森。

0

与Tomasz相似,但具有超出范围的错误处理

enum ArrayError: ErrorType {
    case OutOfRange
}

extension Array {
    mutating func move(fromIndex fromIndex: Int, toIndex: Int) throws {
        if toIndex >= count || toIndex < 0 {
            throw ArrayError.OutOfRange
        }
        insert(removeAtIndex(fromIndex), atIndex: toIndex)
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.