2

我有一个分层的 NSMutableDictionary 对象,我希望能够删除层次结构中更深层次的字典。有没有一种快速简便的方法来做到这一点,例如,类似于 removeObjectAtKeyPath 的方法?好像一个也找不到

谢谢!

4

5 回答 5

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

注意这要求路径的倒数第二个元素 -tailContainer是响应的东西removeObjectForKey:,可能是另一个NSMutableDictionary。如果不是,轰!

于 2013-02-27T07:28:12.887 回答
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);
于 2013-02-27T06:43:56.883 回答
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]];
    }
}
于 2013-12-01T17:33:43.570 回答
0

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

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使用递归来逐步执行keyPath

于 2015-11-09T02:44:48.933 回答
0

我只是对 jscs 接受的答案进行了迭代,并稍作改进——使用NSString's 的内置pathUtlities类别处理 KVC 密钥路径。

@implementation NSMutableDictionary (NestedMutableDictionaries)
- (void)removeObjectForKeyPath: (NSString *)keyPath
{
    NSArray *key = [keyPath pathExtension];
    NSString *keyPathHead = [keyPath stringByDeletingPathExtension];
    [[self valueForKeyPath:keyPathHead] removeObjectForKey:key];
}
@end

稍微好一点,我觉得。

于 2022-01-24T07:17:19.193 回答