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