使用相同的键添加不同NSMutableDictionaries的值

时间:2017-05-10 17:01:33

标签: objective-c nsdictionary xcode8 nsmutabledictionary

我在Xcode 8.2,OSX而不是iOS,Objective-C

我有几个不同的NSMutableDictionaries,如:

NSMutableDictionary* dict1 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                             [NSNumber numberWithInt:1],@"key1",
                             [NSNumber numberWithInt:14],@"key2",
                             nil];

NSMutableDictionary* dict2 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                             [NSNumber numberWithInt:9],@"key1",
                             [NSNumber numberWithInt:1],@"key2",
                             [NSNumber numberWithInt:99],@"key3",
                             nil];

// and many more

我需要以添加匹配键的值的方式组合它们,这样我们就可以得到一个新的NSMutableDictionary(或者结果不可变),如上例所示:

NSMutableDictionary* result = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                             [NSNumber numberWithInt:10],@"key1", // 9+1
                             [NSNumber numberWithInt:15],@"key2", // 14+1
                             [NSNumber numberWithInt:99],@"key3", // stays the same
                             nil];

2 个答案:

答案 0 :(得分:0)

这是一个通用的合并词典,它采用一个块来解决冲突。

NSDictionary *mergeDictionaries( NSDictionary *left,
                                NSDictionary *right,
                                id (^resolveConflict)(id duplicateKey, id leftValue, id rightValue)
                                ) {

    NSArray *sharedKeys = [[left allKeys] filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"%@ CONTAINS SELF", [right allKeys]]];

    NSMutableArray *leftOnlyKeys = [[left allKeys] mutableCopy];
    [leftOnlyKeys removeObjectsInArray: [right allKeys]];

    NSMutableArray *rightOnlyKeys = [[right allKeys] mutableCopy];
    [rightOnlyKeys removeObjectsInArray: [left allKeys]];

    NSMutableDictionary *merged = [[NSMutableDictionary alloc] init];

    [leftOnlyKeys enumerateObjectsUsingBlock:^(id  _Nonnull key, NSUInteger idx, BOOL * _Nonnull stop) {
        [merged setObject: left[key] forKey: key];
    }];

    [rightOnlyKeys enumerateObjectsUsingBlock:^(id  _Nonnull key, NSUInteger idx, BOOL * _Nonnull stop) {
        [merged setObject: right[key] forKey: key];
    }];

    if(resolveConflict) {
        [sharedKeys enumerateObjectsUsingBlock:^(id  _Nonnull key, NSUInteger idx, BOOL * _Nonnull stop) {
            id mergedValue = resolveConflict(key, left[key], right[key]);
            if(nil != mergedValue) {
                [merged setObject: mergedValue forKey: key];
            }
        }];
    }

    return merged;
}

然后

NSMutableDictionary* dict1 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                              [NSNumber numberWithInt:1],@"key1",
                              [NSNumber numberWithInt:14],@"key2",
                              nil];

NSMutableDictionary* dict2 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                              [NSNumber numberWithInt:9],@"key1",
                              [NSNumber numberWithInt:1],@"key2",
                              [NSNumber numberWithInt:99],@"key3",
                              nil];

NSDictionary *merged = mergeDictionaries(dict1, dict2, ^id(NSObject *key, NSNumber *lhs, NSNumber *rhs) {
    return [NSNumber numberWithInt: ([lhs intValue] + [rhs intValue])];
});

NSLog(@"result : %@", merged);

产量

  

结果:{       key1 = 10;       key2 = 15;       key3 = 99; }

答案 1 :(得分:0)

你走了:

NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
for (NSDictionary *dictionary in @[dict1, dict2]) {
    // enumerate the keys and objects in the dictionary
    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSNumber *dictionaryNumber, BOOL *stop){
        // check if the key exists in result
        NSNumber *resultNumber = result[key];
        if (resultNumber)
            // the key exists in result, add the number to the existing number
            result[key] = [NSNumber numberWithInteger:resultNumber.integerValue + dictionaryNumber.integerValue];
        else
            // the key didn't exist in result, add the key and the number to result
            result[key] = dictionaryNumber;
    }];
}