【问题标题】:How to rename a Key in NSMutableDictionary?如何重命名 NSMutableDictionary 中的键?
【发布时间】:2011-02-02 07:00:03
【问题描述】:

我有一个NSMutableDictionary。我必须在我的代码中将字典中的任何 Key 动态重命名为新值。我找不到任何内置 API 来执行此操作。

我该怎么做?是否有任何内置 API 可用于执行此操作?

谢谢大家..

【问题讨论】:

  • 是否可以选择将值复制出来,然后创建一个具有所需名称的新键?
  • 我不能直接编辑现有的密钥?

标签: iphone objective-c cocoa cocoa-touch


【解决方案1】:
// assumes that olkdey and newkey won't be the same; they can't as
// constants... but...
[dict setObject: [dict objectForKey: @"oldkey"] forKey: @"newkey"];
[dict removeObjectForKey: @"oldkey"];

想想“直接编辑现有密钥”是什么意思。字典是散列;它对键的内容进行哈希处理以找到一个值。

如果您要更改密钥的内容会发生什么?键需要重新散列(并重新平衡字典的内部结构),否则值将不再可检索。

为什么首先要编辑密钥的内容? IE。上面没有解决什么问题?

【讨论】:

  • 谢谢..这很好..我不能直接编辑现有的密钥?
  • 嗯..没什么特别的..我只是希望有一种直接编辑密钥的方法..就是这样..谢谢伙计..
  • 感谢@bbum,这也适用于 NSUserdefault!
  • 如果 oldkey 等于 newkey 则失败
  • @de。在这个人为的例子中,它不会失败,因为它们不是变量。但当然值得注意!
【解决方案2】:

这应该可行:

- (void) renameKey:(id<NSCopying>)oldKey toKey:(id<NSCopying>)newKey{
    NSObject *object = [dictionary objectForKey:oldKey];
    [object retain];
    [dictionary removeObjectForKey:oldKey];
    [dictionary setObject:object forKey:newKey];
    [object release];
}

这与 bbum 的答案完全相同,但是,如果您首先删除旧密钥(如本例中所示),那么您必须暂时保留该对象,否则它可能会以这种方式被释放;)

结论:除非您需要明确删除旧密钥,否则请先做 bbum。

【讨论】:

  • 这也明显更具防御性和通用性;如果 oldKey 和 newKey 是同一个字符串,它仍然可以工作(尽管它做了一些额外的工作)。
【解决方案3】:
@interface NSMutableDictionary (KAKeyRenaming)
- (void)ka_replaceKey:(id)oldKey withKey:(id)newKey;
@end

@implementation NSMutableDictionary (KAKeyRenaming)
- (void)ka_replaceKey:(id)oldKey withKey:(id)newKey
{
    id value = [self objectForKey:oldKey];
    if (value) {
        [self setObject:value forKey:newKey];
        [self removeObjectForKey:oldKey];
    }
}
@end

这也可以很好地处理字典没有键值的情况。

【讨论】:

  • 另一个不错的解决方案;但是在这些方法前面加上一些不通用的东西,如果有的话,可能会与框架中的一些未来添加物发生冲突......
  • @bbum 是对的:为自定义类和协议添加前缀应该被视为一项要求。为了完美而编辑。
  • 类别名称无所谓;在运行时不可用。您必须担心的是方法名称....
  • 新旧密钥相同时的结果是什么。这听起来可能是一个愚蠢的问题,但不幸的是,我遇到了类似的情况。键在少数情况下相同,字符串的大小写(大写、小写或组合)不同。我从服务器获取密钥,不能相信两者会有所不同,而且我的移动客户端也应该准备好在这种情况下采取行动。如果您对此场景有解决方案,请发表评论。
【解决方案4】:

我必须导航一个包含字段、子字典和子数组的完整 JSON 响应对象。因为其中一个 JSON 字段称为“return”,它是 iOS 保留字,因此不能与 JSONModel Cocoa Pod 一起使用。 代码如下:

+ (id) sanitizeJSON:(id) dictIn {
if (dictIn) //check not null
{
    // if it's a dictionary item
    if ([dictIn isKindOfClass:[NSDictionary class]])
    {
        NSMutableDictionary *dictOut = [dictIn mutableCopy]; 
        // Do the fix replace "return" with "not_return"
        if ([dictOut objectForKey: @"return"])
        {[dictOut setObject: [dictIn objectForKey: @"return"] forKey: @"not_return"];
         [dictOut removeObjectForKey: @"return"];}

        // Continue the recursive walk through
        NSArray*keys=[dictOut allKeys]; //get all the keys
        for (int n=0;n<keys.count;n++)
        {
           NSString *key = [keys objectAtIndex:n];
           //NSLog(@"key=%@ value=%@", key, [dictOut objectForKey:key]);
           if (([[dictOut objectForKey:key] isKindOfClass:[NSDictionary class]]) || ([[dictOut objectForKey:key] isKindOfClass:[NSArray class]]))
            {
                // recursive call
                id sanitizedObject =  [self sanitizeJSON:[dictOut objectForKey:key]];
                [dictOut removeObjectForKey: key];
                [dictOut setObject:sanitizedObject forKey:key];
                // replace returned (poss modified) item with this one
            }
        }
        return dictOut; //return dict
    }
    else if ([dictIn isKindOfClass:[NSArray class]]) //Or if it's an array item
    {

        NSMutableArray *tempArray = [dictIn mutableCopy];
        // Do the recursive walk across the array
        for (int n=0;n< tempArray.count; n++)
        {
            // if array item is dictionary
            if (([[tempArray objectAtIndex:n] isKindOfClass:[NSDictionary class]]) || ([[tempArray objectAtIndex:n] isKindOfClass:[NSArray class]]))
            {
                // recursive call
                id sanitizedObject =  [self sanitizeJSON:[tempArray objectAtIndex:n]];
                // replace with the possibly modified item
                [tempArray replaceObjectAtIndex:n withObject:sanitizedObject];
            }
        }
        return tempArray; //return array
    }
    return dictIn; //Not nil or dict or array
}
else
  return dictIn; //return nil 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2011-02-11
    • 2020-04-20
    • 2011-09-05
    • 2017-09-08
    • 2018-08-16
    • 2020-11-26
    相关资源
    最近更新 更多