Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 从NSArray获取NSIndexSet_Cocoa_Arrays_Nsarray_Nsindexset - Fatal编程技术网

Cocoa 从NSArray获取NSIndexSet

Cocoa 从NSArray获取NSIndexSet,cocoa,arrays,nsarray,nsindexset,Cocoa,Arrays,Nsarray,Nsindexset,NSArray提供了一些有用的方法来查找指定索引的对象 // To find objects by indexes - (id)objectAtIndex:(NSUInteger)index - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes // To find index by object - (NSUInteger)indexOfObject:(id)anObject 但是,我想为给定对象获取NSIndexSet(多个索引)。比如:

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
,此方法不存在。我错过什么了吗?有人知道另一种标准方法吗?否则,我必须将其作为类别方法编写。

据我所知,您必须实现自己的类别。

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

- (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;
}
这样,如果您正在扫描一个20000项的数组中的两个对象,并且它们都位于前十个对象的内部,则可以避免扫描数组中的其他19'990个对象。但是,正如我所说的,如果数组包含重复项,则这没有帮助,因为一旦找到2个索引(即使它们都指向同一个对象),它就会停止

话虽如此,我同意迈克的上述评论。很有可能你会让自己陷入痛苦之中。可能值得考虑不同的数据类型;例如,对于一个简单的平面容器,NSArray似乎是最合理的选择,但是如果您实际上不需要订购信息,那么最好使用NSSet;这还有一个额外的优点,即它不会存储同一对象(使用
-isEqual:
计算)两次。如果您确实希望跟踪重复项,但不需要排序,则可以使用NSCountedSet,它的行为与NSSet相同,只是它跟踪每个对象的添加/删除次数,而不实际存储重复项。

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

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

但是请注意,想要使用这种方法是设计缺陷的一个明显标志-IndexOfoObject:通过搜索数组中的每个对象来工作,因此对于大型数组或多个搜索变得非常缓慢。重新思考您的数据结构,寻找更合理的方法。+1只是一个小提示:“索引”和“索引”在英语中都是正确的,但Cocoa总是使用“索引”,因此最好保持这个术语,至少在方法名称上是这样。