8

我已经尝试合并两个 NSDictionaries 几个小时了。搜索了一下,发现可以用[NSMutableDictionary addEntriesFromDictionary:]

    NSDictionary *areaAttributes = [[area entity] attributesByName];
    NSDictionary *gpsAttributes = [[gps entity] attributesByName];

    NSMutableDictionary *areaAttributesM = [areaAttributes mutableCopy];
    NSMutableDictionary *gpsAttributesM = [gpsAttributes mutableCopy];

    NSMutableDictionary *combinedAttributes =  [areaAttributesM addEntriesFromDictionary:gpsAttributesM];

但我得到了错误:

Initializing 'NSMutableDictionary *_strong' with an expression of incompatible type 'void'

所以这是说[areaAttributesM addEntriesFromDictionary:gpsAttributesM]返回void?我的理解正确吗?为什么它返回无效?

4

2 回答 2

13

是的,你是对的。从文档

- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary

至于为什么,这很简单:在 Cocoa 中改变对象的函数通常返回 void,因此您可以轻松地将它们与返回不同对象的函数区分开来。

mutableCopy此外,gpsAttributes字典没有理由。它只是被用作 的参数-[addEntriesFromDictionary:],它不需要是可变的。

所以,正确的做法是:

NSDictionary *areaAttributes = [[area entity] attributesByName];
NSDictionary *gpsAttributes = [[gps entity] attributesByName];

NSMutableDictionary *combinedAttributes = [areaAttributes mutableCopy];
[combinedAttributes addEntriesFromDictionary:gpsAttributes];

NSDictionary如果您经常这样做,您可能希望将其包装在一个函数(或类别中的方法)中:

NSDictionary *mergeDictionaries(NSDictionary *lhs, NSDictionary *rhs) {
    NSMutableDictionary *ret = [lhs mutableCopy];
    [ret addEntriesFromDictionary:rhs];
    return ret;
}
于 2013-01-14T23:13:23.367 回答
0

从文档中, addEntriesFromDictionary 告诉我们:

如果两个字典包含相同的键,则接收字典的该键的先前值对象将被发送一条释放消息,并且新的值对象将取代它。您需要使用 setObject 将每个对象添加到字典中。您需要遍历一个字典的键并将其添加到最终字典中。

甚至 setObject 也一样:

价值的关键。密钥被复制(使用 copyWithZone:; 密钥必须符合 NSCopying 协议)。如果字典中已经存在 aKey,则使用 anObject 代替它。字典中不能有两个相同的键。字典中的所有键都是唯一的。

如果您仍然希望在字典中具有相同的键值,则必须使用不同的键。

例如,您有两个具有以下值的字典:

NSDictionary *dict1=@{@"hello":@"1",@"hello2" :@"2"};
NSDictionary *dict2=@{@"hello":@"1",@"hello2":@"2",@"hello3":@"1",@"hello6":@"2",@"hello4":@"1",@"hello5" :@"2"};

 NSMutableDictionary *mutableDict=[NSMutableDictionary dictionaryWithDictionary:dict1];
    for (id key in dict2.allKeys){
        for (id subKey in dict1.allKeys){
            if (key==subKey) {
                [mutableDict setObject:dict2[key] forKey:[NSString stringWithFormat:@"Ext-%@",key]];
            }else{
                [mutableDict setObject:dict2[key] forKey:key];
            }
        }
    }

在此循环结束时,您的新可变字典将具有以下键值:

{
    "Ext-hello" = 1;
    "Ext-hello2" = 2;
    hello = 1;
    hello2 = 2;
    hello3 = 1;
    hello4 = 1;
    hello5 = 2;
    hello6 = 2;
}

如您所见,hello 和 hello2 键被重命名为 Ext-hello1、Ext-hello2。形成 dict1,并且您仍然将所有 dict2 值添加到可变 dict 中。

如果您不想添加新键,则可以将值添加到 arrya 并将该数组添加到字典中。您可以将 for 循环修改为:

for (id key in dict2.allKeys){
    for (id subKey in dict1.allKeys){
        if (key==subKey) {
            NSMutableArray *myArr=[[NSMutableArray alloc]init];
            [myArr addObject:dict1[subKey]];
            [myArr addObject:dict2[key]];
            [mutableDict setObject:myArr forKey:key];
        }else{
            [mutableDict setObject:dict2[key] forKey:key];
        }
    }
}

现在您将值合并到一个数组中:

{
    hello =     (
        1,
        1
    );
    hello2 = 2;
    hello3 = 1;
    hello4 = 1;
    hello5 = 2;
    hello6 = 2;
}

这样,键的数量将相同,并且相同键的值将作为数组添加。

于 2016-07-25T16:29:08.183 回答