NSMutableDictionary在关键路径中删除对象?

时间:2013-02-27 06:38:20

标签: ios objective-c nsmutabledictionary key-value-coding

我有一个分层的NSMutableDictionary对象,我希望能够删除层次结构中更深层次的词典。有没有一种快速简便的方法来执行此操作,例如,类似removeObjectAtKeyPath的方法?似乎无法找到一个。

谢谢!

4 个答案:

答案 0 :(得分:4)

没有内置,但你的基本类别方法会很好:

@implementation NSMutableDictionary (WSSNestedMutableDictionaries)

- (void)WSSRemoveObjectForKeyPath: (NSString *)keyPath
{
    // Separate the key path
    NSArray * keyPathElements = [keyPath componentsSeparatedByString:@"."];
    // Drop the last element and rejoin the path
    NSUInteger numElements = [keyPathElements count];
    NSString * keyPathHead = [[keyPathElements subarrayWithRange:(NSRange){0, numElements - 1}] componentsJoinedByString:@"."];
    // Get the mutable dictionary represented by the path minus that last element
    NSMutableDictionary * tailContainer = [self valueForKeyPath:keyPathHead];
    // Remove the object represented by the last element
    [tailContainer removeObjectForKey:[keyPathElements lastObject]];
}

@end

N.B。这个需要路径的倒数第二个元素 - tailContainer是响应removeObjectForKey:的东西,可能是另一个NSMutableDictionary。如果不是,那就狂热吧!

答案 1 :(得分:0)

您可以创建一个类别:

这是最多1级:

#import "NSMutableDictionary+RemoveAtKeyPath.h"

@implementation NSMutableDictionary (RemoveAtKeyPath)

-(void)removeObjectAtKeyPath:(NSString *)keyPath{

    NSArray *paths=[keyPath componentsSeparatedByString:@"."];

    [[self objectForKey:paths[0]] removeObjectForKey:paths[1]];

}

@end

它被称为:

NSMutableDictionary *adict=[[NSMutableDictionary alloc]initWithDictionary:@{@"key1" : @"obj1", @"key11":@"obj11"}];

NSMutableDictionary *bdict=[[NSMutableDictionary alloc]initWithDictionary:@{@"key2" : adict}];

NSLog(@"%@",bdict);
NSLog(@"%@",[bdict valueForKeyPath:@"key2.key1"]);

[bdict removeObjectAtKeyPath:@"key2.key1"];
NSLog(@"After category : %@",bdict);

答案 2 :(得分:0)

为了处理不包含句点的密钥路径(即实际上是密钥的密钥路径),对Josh的答案进行了小的改进:

- (void)removeObjectAtKeyPath:(NSString *)keyPath
{
    NSArray *keyPathElements = [keyPath componentsSeparatedByString:@"."];
    NSUInteger numElements = [keyPathElements count];
    if (numElements == 1) {
        [self removeObjectForKey:keyPath];
    } else {
        NSString *keyPathHead = [[keyPathElements subarrayWithRange:(NSRange){0, numElements - 1}] componentsJoinedByString:@"."];
        NSMutableDictionary *tailContainer = [self valueForKeyPath:keyPathHead];
        [tailContainer removeObjectForKey:[keyPathElements lastObject]];
    }
}

答案 3 :(得分:0)

我知道这是一篇较老的帖子,但我需要在Swift 2.0中找到相同的解决方案,无法找到我想出的解决方案的简单答案:

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
[dictionary setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
[dictionary setObject:(__bridge id)kSecAttrAccess forKey:(__bridge id)kSecAttrAccessGroup];

NSArray *secItemClasses = [NSArray arrayWithObjects:
                           (__bridge id)kSecClassGenericPassword,
                           (__bridge id)kSecClassInternetPassword,
                           (__bridge id)kSecClassIdentity,
                           (__bridge id)kSecClassKey,
                           (__bridge id)kSecClassCertificate,
                           nil];

int count = 0;
for (id secItemClass in secItemClasses) {
    [dictionary setObject:secItemClass forKey:kSecClass];
    CFTypeRef result = nil;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, &result);

    if(status == noErr)
    {
        NSArray *arr = (__bridge_transfer NSArray *)result;
        count+= arr.count;
        NSLog(@"%@",arr);
        [self showLog:[arr description]];
    }
    else if(status == errSecNoAccessForItem)
    {
        NSLog(@"errSecNoAccessForItem");
        [self showLog:@"errSecNoAccessForItem\n"];
    }
    else if(status == errSecItemNotFound)
    {
        NSLog(@"errSecItemNotFound");
        [self showLog:@"errSecItemNotFound\n"];
    }
}

我已经使用递归添加了public extension NSMutableDictionary { public func removeObjectAtKeyPath(keyPath:String) { let elements = keyPath.componentsSeparatedByString(".") let head = elements.first! if elements.count > 1 { let tail = elements[1...elements.count-1].joinWithSeparator(".") if let d = valueForKeyPath(head) as? NSMutableDictionary { d.removeObjectAtKeyPath(tail) } }else{ removeObjectForKey(keyPath) } } } 的扩展程序来逐步执行NSMutableDictionary