私は現在、json-framework の助けを借りてNSDictionary
、いくつかの値がオブジェクトに設定されている場所を持っています。NSNull
目的は、すべてのNSNull
値を取り除き、空の文字列に置き換えることです。
誰かがどこかでこれをやったと確信していますか?間違いなく、それはおそらく 4 つのライナーであり、シンプルです。
私は現在、json-framework の助けを借りてNSDictionary
、いくつかの値がオブジェクトに設定されている場所を持っています。NSNull
目的は、すべてのNSNull
値を取り除き、空の文字列に置き換えることです。
誰かがどこかでこれをやったと確信していますか?間違いなく、それはおそらく 4 つのライナーであり、シンプルです。
本当に簡単です:
@interface NSDictionary (JRAdditions)
- (NSDictionary *)dictionaryByReplacingNullsWithStrings;
@end
@implementation NSDictionary (JRAdditions)
- (NSDictionary *)dictionaryByReplacingNullsWithStrings {
const NSMutableDictionary *replaced = [self mutableCopy];
const id nul = [NSNull null];
const NSString *blank = @"";
for(NSString *key in self) {
const id object = [self objectForKey:key];
if(object == nul) {
//pointer comparison is way faster than -isKindOfClass:
//since [NSNull null] is a singleton, they'll all point to the same
//location in memory.
[replaced setObject:blank
forKey:key];
}
}
return [replaced copy];
}
@end
使用法:
NSDictionary *someDictThatHasNulls = ...;
NSDictionary *replacedDict = [someDictThatHasNulls dictionaryByReplacingNullsWithStrings];
この問題に取り組む 1 つの方法は、辞書を調べて NSNull を探すことですが、私は少し怠惰なアプローチを取りました。nil の代わりに空の文字列を割り当てることもできますが、原則は同じです。
@interface NSDictionary (CPJSONDictionary)
- (id)jsonObjectForKey:(id)aKey;
@end
@implementation NSDictionary (CPJSONDictionary)
- (id)jsonObjectForKey:(id)aKey {
id object = [self objectForKey:aKey];
if ([object isKindOfClass:[NSNull class]]) {
object = nil;
}
return object;
}
@end
Stakenborg ソリューションをテストしました。それはうまく機能しますが、次の問題があります。たとえば、一部のオブジェクトが数値であると予想される場合、それを数値に変換するとNSNull
エラーが発生する可能性があります。NSNull
エントリを直接削除する新しいメソッドを作成しました。この方法では、対応するキーが存在することを確認するだけで済みます。
加えるNSDictionary+NullReplacement
- (NSDictionary *)dictionaryByRemovingNulls{
const NSMutableDictionary *replaced = [self mutableCopy];
const id nul = [NSNull null];
for (NSString *key in self) {
id object = [self objectForKey:key];
if (object == nul) [replaced removeObjectForKey:key];
else if ([object isKindOfClass:[NSDictionary class]]) [replaced setObject:[object dictionaryByRemovingNulls] forKey:key];
else if ([object isKindOfClass:[NSArray class]]) [replaced setObject:[object arrayByRemovingNulls] forKey:key];
}
return [NSDictionary dictionaryWithDictionary:[replaced copy]];
}
そして、NSArray+NullReplacement
- (NSArray *)arrayByRemovingNulls {
NSMutableArray *replaced = [self mutableCopy];
const id nul = [NSNull null];
for (int idx = [replaced count]-1; idx >=0; idx--) {
id object = [replaced objectAtIndex:idx];
if (object == nul) [replaced removeObjectAtIndex:idx];
else if ([object isKindOfClass:[NSDictionary class]]) [replaced replaceObjectAtIndex:idx withObject:[object dictionaryByRemovingNulls]];
else if ([object isKindOfClass:[NSArray class]]) [replaced replaceObjectAtIndex:idx withObject:[object arrayByRemovingNulls]];
}
return [replaced copy];
}
別のバリエーション:
NSDictionary * NewDictionaryReplacingNSNullWithEmptyNSString(NSDictionary * dict) {
NSMutableDictionary * const m = [dict mutableCopy];
NSString * const empty = @"";
id const nul = [NSNull null];
NSArray * const keys = [m allKeys];
for (NSUInteger idx = 0, count = [keys count]; idx < count; ++idx) {
id const key = [keys objectAtIndex:idx];
id const obj = [m objectForKey:key];
if (nul == obj) {
[m setObject:empty forKey:key];
}
}
NSDictionary * result = [m copy];
[m release];
return result;
}
結果は同じで、Jacob のものとほとんど同じように見えますが、私が行ったテストでは、速度とメモリの要件は 2 分の 1 から 3 分の 1 (ARC または MRC) です。もちろん、カテゴリメソッドとしても使用できます。
-(NSDictionary*)stripNulls:(NSDictionary*)dict{
NSMutableDictionary *returnDict = [NSMutableDictionary new];
NSArray *allKeys = [dict allKeys];
NSArray *allValues = [dict allValues];
for (int i=0; i<[allValues count]; i++) {
if([allValues objectAtIndex:i] == (NSString*)[NSNull null]){
[returnDict setValue:@"" forKey:[allKeys objectAtIndex:i]];
}
else
[returnDict setValue:[allValues objectAtIndex:i] forKey:[allKeys objectAtIndex:i]];
}
return returnDict;
}