如何交换`NSMutableDictionary`键和值?

时间:2013-10-15 17:44:10

标签: iphone ios nsmutabledictionary

我有一个NSMutableDictionary我希望交换价值&键。即,交换后的值变为键,其对应的键变为值所有键和值都是唯一的。寻找一个到位的解决方案,因为尺寸非常大。此外,键和值为NSString个对象

5 个答案:

答案 0 :(得分:16)

NSMutableDictionary *d = [NSMutableDictionary dictionaryWithDictionary:@{
                             @"key1" : @"value1",
                             @"key2" : @"value2"}];

for (NSString *key in [d allKeys]) {
    d[d[key]] = key;
    [d removeObjectForKey:key];
}

NSLog(@"%@", d); // => { value1 : key1,
                 //      value2 : key2 }

假设

  • 唯一值(因为它们将成为键)
  • 值符合NSCopying(与上述相同)
  • 没有值等于任何键(否则在此过程中会丢失碰撞名称)

答案 1 :(得分:5)

这是另一种反转字典的方法。对我来说最简单。

NSArray *keys = dictionary.allKeys;
NSArray *values = [dictionary objectsForKeys:keys notFoundMarker:[NSNull null]];
[dictionary removeAllObjects]; // In case of huge data sets release the contents.
NSDictionary *invertedDictionary = [NSDictionary dictionaryWithObjects:keys forKeys:values];
[dictionary setDictionary:invertedDictionary]; // In case you want to use the original dictionary.

答案 2 :(得分:-1)

编辑:我写了几行代码,让OP开始创建自己的算法。答案没有得到很好的接受,所以我已经精心设计了一个算法的完整实现,可以完成他所要求的,并且更进一步。

优点:

  • 不对字典的内容做任何假设,例如,值不需要符合'NSCopying'协议
  • 横切整个集合的层次结构,交换所有密钥
  • 它很快,因为它使用递归和快速枚举
  • 不会改变原始字典的内容,而是创建一个全新的字典

代码已通过两个集合的类别实施:

@interface NSDictionary (Swapping)

- (NSDictionary *)dictionaryBySwappingKeyWithValue;

@end

@interface NSDictionary (Swapping)

- (NSDictionary *)dictionaryBySwappingKeyWithValue
{
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:self.count];

    [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
        id newKey = nil;
        if ([value isKindOfClass:[NSDictionary class]]) {
            newKey = [value dictionaryBySwappingKeyWithValue];

        } else if ([value isKindOfClass:[NSArray class]]) {
            newKey = [value arrayBySwappingKeyWithValue];
        } else {
            newKey = value;
        }

        if (![newKey conformsToProtocol:@protocol(NSCopying)]) {
            newKey = [NSValue valueWithNonretainedObject:newKey];
        }

        mutableDictionary[newKey] = key;
    }];

    return [NSDictionary dictionaryWithDictionary:mutableDictionary];
}

@end

和...

@interface NSArray (Swapping)

- (NSArray *)arrayBySwappingKeyWithValue;

@end

@implementation NSArray (Swapping)

- (NSArray *)arrayBySwappingKeyWithValue
{
    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:self.count];

    [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj isKindOfClass:[NSDictionary class]]) {
            NSDictionary *newDict = [obj dictionaryBySwappingKeyWithValue];
            mutableArray[idx] = newDict;
        } else if ([obj isKindOfClass:[NSArray class]]) {
            NSArray *newArray = [obj arrayBySwappingKeyWithValue];
            mutableArray[idx] = newArray;
        } else {
            mutableArray[idx] = obj;
        }
    }];

    return [NSArray arrayWithArray:mutableArray];
}

@end

例如,假设您有一个具有以下结构的字典:

UIView *view = [[UIView alloc] init];
NSDictionary *dict = @{@"1" : @"a",
                       @"2" : @[ @{ @"5" : @"b" } ],
                       @"3" : @{@"6" : @"c"},
                       @"7" : view};

NSDictionary *newDict = [dict dictionaryBySwappingKeyWithValue];

在控制台中打印newDict对象将为您提供此输出:

(lldb) po mutableDictionary
{
    a = 1;
    ({b = 5;}) = 2;
    {c = 6;} = 3;
    "<30b50617>" = 7; 
}

正如您所看到的,不仅在层次结构的第一级交换了键和值,而且在每个集合的内部都进行了交换。

"<30b50617>"表示包含在NSValue中的UIView对象。由于UIView不符合NSCopying协议,因此如果您希望它成为集合中的密钥,则需要以这种方式处理。

注意:代码在几分钟内完成。如果我错过了什么,请告诉我。

答案 3 :(得分:-1)

for (NSString *key in [myDictionary allKeys]) {
     NSString *value = [responseDataDic objectForKey:key];
     [myDictionary removeObjectForKey:key];
     [myDictionary addObject:key forKey:value];
}

假设: 没有键=值;

复杂性: 无需额外空间。将遍历一次并替换所有键值对。

答案 4 :(得分:-2)

NSArray* allKeys = [theDict allKeys];
NSArray* allValues = [theDict allValues];
NSMutableDictionary* newDict = [NSMutableDictionary dictionaryWithObjects:allKeys forKeys:allValues];