从 NSArray 获取 NSIndexSet

发布于 2024-07-21 08:09:55 字数 454 浏览 12 评论 0原文

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

NSArray has useful methods to find objects for specified indexes

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

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

However, I want to get NSIndexSet (multiple indexes) for given objects. Something like:

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

This method does not exist for NSArray. Am I missing something? Does someone know another standard method? Otherwise I have to write this as a category method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄荷→糖丶微凉 2024-07-28 08:09:55

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

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

Newer NSArray versions (OSX 10.6 and iOS 4) provides the indexesOfObjectsPassingTest: method.

NSIndexSet *indexesOfObjects = [[array1 indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [array2 containsObject:obj];
}];
三生池水覆流年 2024-07-28 08:09:55

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

- (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 类似,只是它跟踪每个对象已添加/删除的次数,而不实际存储重复项。

It might be useful to implement it using a set to specify the objects to find, such as:

- (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] );
}

This requires visiting every object in the array, but at least only does so once and makes use of fast enumeration while doing so. Using an NSSet and testing each object in the array against that set is also much faster than testing for inclusion in an array.

There's a potential optimization here, but it would break in the case where a single object is stored in the receiving array multiple times:

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

That way if you're scanning a 20'000-item array for two objects and they're both inside the first ten, you'll be able to avoid scanning the other 19'990 objects in the array. As I said though, that doesn't help if the array contains duplicates, because it'll stop as soon as it's found 2 indices (even if they both point to the same object).

Having said that, I agree with Mike's comment above. Chances are you're setting yourself up for some pain come optimization-time. It may be worth thinking about different data types; for instance, while NSArray seems the most logical choice for a simple flat container, if you don't actually need the ordering information it's better to use an NSSet instead; this has the added advantage that it won't store the same object (calculated using -isEqual:) twice. If you do want to keep track of duplicates, but don't need ordering, you can use NSCountedSet, which behaves as NSSet except it keeps track of how many times each objects has been added/removed without actually storing duplicates.

半窗疏影 2024-07-28 08:09:55

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

You have to implement your own category, as far as I can see.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文