8

我有一个基于唯一整数键的数据集的未确定大小。

我想使用NSMutableArray快速查找,因为我所有的键都是基于整数的。

我想做这个。

NSMutableArray* data = [NSMutableArray array]; // just create with 0 size

然后以后人们会开始用整数索引(都是唯一的)向我扔数据,所以我只想做这样的事情......

if ([data count] < index)
    [data resize:index];  // ? how do you resize

并调整数组的大小,以便我可以做......

[data insertObject:obj atIndex:index];

最后大小和新大小之间的所有插槽都为零,最终将在以后填充。

所以我的问题是如何调整现有的大小NSMutableArray

谢谢,罗马

4

4 回答 4

32

使用 NSPointerArray。

http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSPointerArray_Class/Introduction/Introduction.html

NSPointerArray 是一个以 NSArray 为模型的可变集合,但它也可以保存 NULL 值,可以插入或提取(并有助于对象的计数)。而且,与传统数组不同,您可以直接设置数组的计数。在垃圾收集环境中,如果您指定归零弱内存配置,则如果收集了一个元素,则将其替换为 NULL 值。

如果您要使用类似字典的解决方案,请使用 NSMapTable。它允许整数键。推荐的基于 NSMutableDictionary 的解决方案具有与整数键的所有装箱和拆箱相关的大量开销。

于 2009-08-31T15:02:25.457 回答
19

听起来您的需求会更好地满足NSMutableDictionary. 您需要将ints 包装到NSNumber对象中,如下所示:

-(void)addItem:(int)key value:(id)obj
{
    [data setObject:obj forKey:[NSNumber numberWithInt:key]];
}

-(id)getItem:(int)key
{
    return [data objectForKey:[NSNumber numberWithInt:key]];
}

扩大 an 的大小并不容易NSMutableArray,因为在中间的插槽中不能有 nil 对象。但是,您可以将[NSNull null]其用作“填充物”来创建稀疏数组的外观。

于 2009-08-30T21:39:44.220 回答
1

正如杰森的回答一样, NSMutableDictionary 似乎是最好的方法。它增加了将索引值与 NSNumber 相互转换的开销,但这是典型的空间/时间折衷。

在我的实现中,我还包含了一个 NSIndexSet 来简化遍历稀疏数组的过程。

https://github.com/LavaSlider/DSSparseArray

于 2014-05-26T17:38:33.627 回答
-3

我不得不不同意bbum对此的回答。ANSPointerArray是数组,不是稀疏数组,两者有重要区别。

强烈建议不要使用 bbums 解决方案。

的文档NSPointerArray在此处获得。

Cocoa 已经有一个类定义的数组对象NSArrayNSPointerArray继承自NSObject,因此它不是 的直接子类NSArray。但是,NSPointerArray文档将类定义为:

NSPointerArray is a mutable collection modeled after NSArray but it can also hold NULL values

我将做出一个公理假设,即文档中的这个定义断言这是NSArray.

定义-

“通用”数组是:项目的集合,每个项目都有一个唯一的索引号与之关联。

一个没有限定条件的数组是: 一个“通用”数组,其中项的索引具有以下属性: 数组中项的索引开始于0并按顺序增加。数组中的所有项包含的索引号小于数组中的项数。向数组中添加项必须在数组中最后一项的索引 + 1 处,或者可以在两个现有项索引号之间插入一个项,这会导致所有后续项的索引号加一。现有索引号的项目可以被另一个项目替换,此操作不会更改现有操作的索引号。因此,插入和替换是两个不同的操作。

稀疏数组是:一个“一般”数组,其中第一项的索引号可以从任意数字开始,并且添加到数组中的后续项的索引号与数组中的其他项没有关系或限制。将项目插入稀疏数组不会影响数组中其他项目的索引号。在大多数实现中,插入项目和替换项目通常是同义词。稀疏数组中项的计数与稀疏数组中项的索引号无关。

这些定义对可测试的“黑盒”数组的行为做出了某些预测。为简单起见,我们将关注以下关系:

在数组中,数组中所有项的索引号小于数组中项数的计数。虽然这可能适用于稀疏数组,但这不是必需的。

在对 bbum 的评论中,我陈述了以下内容:

aNSPointerArray不是稀疏数组,它的行为也不像一个。您仍然必须用NULL指针填充所有未使用的索引。来自[pointerArray insertPointer:@"test" atIndex:17];新实例化的输出NSPointerArray

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcretePointerArray insertPointer:atIndex:]: attempt to insert pointer at index 17 beyond bounds 0'

据说,没有证明,上述行为NSPointerArray违反了稀疏数组的定义。错误消息的这一部分揭示了:attempt to insert pointer at index 17 beyond bounds 0',特别是关于必须在 index 处添加第一个新项目的部分0

bbum 然后评论:

这是不正确的。您未能调用 -setCount: 将容量设置为足够的大小。

对稀疏数组中的项目数进行“设置计数”是没有意义的。如果NSPointerArray是一个稀疏数组,人们会期望在索引 17 处添加第一个项目后,其中项目数的计数NSPointerArray将为 1。但是,按照 bbums 的建议,NSPointerArray添加第一个项目后的项目数是18,而不是1

QED- 表明 aNSPointerArray实际上是一个数组,为了讨论的目的, a NSArray

此外,bbum 还提出了以下附加评论:

NSPointerArray 肯定支持漏洞。

这可证明是错误的。数组要求其中包含的所有项目都包含某些内容,即使该内容是“无”。这不适用于稀疏数组。出于本讨论的目的,这正是“洞”的定义。ANSPointerArray不包含holes术语的稀疏数组意义。

这是编写课程的全部要点之一。您必须先设置计数。

对稀疏数组“设置计数”可证明是没有意义的。

内部实现是稀疏数组还是散列等,是实现细节。

这是真的。但是,文档NSPointerArray没有提及它如何实现或管理其项目数组。此外,它没有在任何地方说明NSPointerArray“有效地管理空指针数组”。

QED-bbum 依赖于内部通过稀疏数组有效处理指针的未记录行为。作为未记录的行为,此行为可能随时更改,甚至可能不适用于. 如果存储在其中的最高索引号足够大(~ 2^26),那么这种行为的变化将是灾难性的。NSPointerArrayNULLNSPointerArray

而且,事实上,它并没有作为一大块内存来实现......

同样,这是一个未记录的私有实现细节。依赖这种类型的行为是非常糟糕的编程实践。

于 2009-09-03T23:56:34.863 回答