当前位置:  开发笔记 > 运维 > 正文

从NSArray获取NSIndexSet

如何解决《从NSArray获取NSIndexSet》经验,为你挑选了2个好方法。

NSArray具有查找指定索引的对象的有用方法

// To find objects by indexes
- (id)objectAtIndex:(NSUInteger)index
- (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes

// To find index by object
- (NSUInteger)indexOfObject:(id)anObject

但是,我想获得NSIndexSet给定对象的(多个索引).就像是:

- (NSIndexSet *)indexesOfObjects:(NSArray *)objects

此方法不存在NSArray.我错过了什么吗?有人知道另一种标准方法吗?否则我必须将其写为类别方法.



1> 小智..:

较新的NSArray版本(OSX 10.6和iOS 4)提供了该indexesOfObjectsPassingTest:方法.

NSIndexSet *indexesOfObjects = [[array1 indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [array2 containsObject:obj];
}];



2> Jim Dovey..:

使用set来指定要查找的对象可能很有用,例如:

- (NSIndexSet *) indicesOfObjectsInSet: (NSSet *) set
{
    if ( [set count] == 0 )
        return ( [NSIndexSet indexSet] );

    NSMutableIndexSet * indices = [NSMutableIndexSet indexSet];

    NSUInteger index = 0;
    for ( id obj in self )
    {
        if ( [set containsObject: obj] )
            [indices addIndex: index];

        index++;
    }

    return ( [[indices copy] autorelease] );
}

这需要访问数组中的每个对象,但至少只执行一次,并在执行此操作时使用快速枚举.使用NSSet并针对该集测试数组中的每个对象也比测试包含在数组中要快得多.

这里有一个潜在的优化,但是在单个对象多次存储在接收数组中的情况下它会中断:

if ( [set containsObject: obj] )
{
    [indices addIndex: index];
    if ( [indices count] == [set count] )
        break;
}

这样,如果你为两个物体扫描一个20'000项目的阵列并且它们都在前十个内,你将能够避免扫描阵列中的其他19'990个物体.正如我所说,如果数组包含重复项,那就无济于事,因为它会在找到2个索引后立即停止(即使它们都指向同一个对象).

话虽如此,我同意迈克上面的评论.你有可能让自己陷入困境来优化时间.可能值得考虑不同的数据类型; 例如,虽然NSArray似乎是简单扁平容器最合理的选择,但如果您实际上不需要订购信息,最好使用NSSet; 这有一个额外的好处,它不会存储-isEqual:两次相同的对象(使用计算).如果你想跟踪重复项,但不需要排序,你可以使用NSCountedSet,它表现为NSSet,除了它跟踪每个对象被添加/删除的次数,而不实际存储重复项.


+1只是一个小注释:"索引"和"索引"在英语中都是正确的,但Cocoa总是使用"索引",所以最好保持这个术语,至少对于方法名称.
推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有