1

我试图查找这个问题,但没有运气,我想构建一个函数来创建键和对象的“不可变字典”,其中对象也是一个不可变数组。

我将传递给这个函数的是我创建的一个对象数组,每个对象都有一个键属性,我想用它来对字典中的对象进行分组。

我想出了这个,我测试了它并且它有效,但我想看看是否有更好/更安全的方法来做到这一点。

我确实使用了 ARC,我想确保当我从函数返回时每件事都是不可变的。

- (NSDictionary* )testFunction:(NSArray *)arrayOfObjects
{
    NSMutableDictionary *tmpMutableDic = [[NSMutableDictionary alloc] init];

    for(MyCustomObject *obj in arrayOfObjects)
    {
        if ([tmpMutableDic objectForKey:obj.key] == nil)
        {
            // First time we get this key. add key/value paid where the value is immutable array
            [tmpMutableDic setObject:[NSArray arrayWithObject:obj] forKey:obj.key];
        }
        else
        {
            // We got this key before so, build a Mutable array from the existing immutable array and add the object then, convert it to immutable and store it back in the dictionary.
            NSMutableArray *tmpMutableArray = [NSMutableArray arrayWithArray:[tmpMutableDic objectForKey:obj.key]];
            [tmpMutableArray addObject:obj];
            [tmpMutableDic setObject:[tmpMutableArray copy] forKey:obj.key];
        }
    }

   // Return an immutable version of the dictionary.
   return [tmpMutableDic copy];
}
4

2 回答 2

2

我认为这是很多抄袭。我会等到最后将可变数组转换为不可变数组,而不是每次要添加元素时都复制它:

- (NSDictionary *)testFunction:(NSArray *)arrayOfObjects
{
    NSMutableDictionary *tmpMutableDic = [[NSMutableDictionary alloc] init];

    for(MyCustomObject *obj in arrayOfObjects)
    {
        if ([tmpMutableDic objectForKey:obj.key] == nil)
        {
            // First time we got this key, add array
            [tmpMutableDic setObject:[[NSMutableArray alloc] init] forKey:obj.key];
        }
        // Add the object
        [[tmpMutableDic objectForKey:obj.key] addObject:obj];
    }

    // Convert mutable arrays to immutable
    for (NSString *key in tmpMutableDic.allkeys) {
        [tmpMutableDic setObject:[[tmpMutableDic objectForKey:key] copy] forKey:key];
    }

    // Return an immutable version of the dictionary.
    return [tmpMutableDic copy];
}
于 2013-08-22T20:54:53.133 回答
0

没有内置的一对多字典的概念,所以我认为没有一种更简洁的方法可以准确地实现你所写的内容——当然没有像一大堆其他常见操作那样的单行语法。

也就是说,次要建议是:

使用键值编码来读取键控属性。因此,将您的引用替换obj.key为一次调用[obj valueForKeyPath:keyPath]keyPath作为参数。然后,您只需编写此代码一次。

为了安全起见,您应该检查obj.key不是nil. 如果是这样,那么您最终会这样做[tmpMutableDic setObject:... forKey:nil],这会引发异常,因为字典无法针对nil键存储值。

copy将返回一个不可变字典,但其中的值仍然是可变数组,因为副本很浅。如果您明确想要返回不可变数组,则需要编写一个快速稍微深入的复制函数。

此时,您可能会发现您更喜欢切换到基于键对传入数组进行排序的算法,然后在每次键值更改时逐步创建一个新数组。这样做的好处是你总是知道你用完一个数组的那一刻,这样你就可以将copy它的一个存储到字典中,然后再剪下稍微深一点的副本,尽管是以排序为代价的。

于 2013-08-22T20:06:28.103 回答