13

私は現在、json-framework の助けを借りてNSDictionary、いくつかの値がオブジェクトに設定されている場所を持っています。NSNull

目的は、すべてのNSNull値を取り除き、空の文字列に置き換えることです。

誰かがどこかでこれをやったと確信していますか?間違いなく、それはおそらく 4 つのライナーであり、シンプルです。

4

8 に答える 8

16

本当に簡単です:

@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];
于 2011-11-10T05:00:01.113 に答える
6

この問題に取り組む 1 つの方法は、辞書を調べて NSNull を探すことですが、私は少し怠惰なアプローチを取りました。nil の代わりに空の文字列を割り当てることもできますが、原則は同じです。

CPJSONDictionary.h

@interface NSDictionary (CPJSONDictionary)
- (id)jsonObjectForKey:(id)aKey;
@end

CPJSONDictionary.m

@implementation NSDictionary (CPJSONDictionary)

- (id)jsonObjectForKey:(id)aKey {
    id object = [self objectForKey:aKey];
    if ([object isKindOfClass:[NSNull class]]) {
        object = nil;
    }

    return object;
}

@end
于 2012-11-29T11:57:19.493 に答える
4

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];
}
于 2014-04-14T11:11:48.713 に答える
3

別のバリエーション:

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) です。もちろん、カテゴリメソッドとしても使用できます。

于 2011-11-10T05:06:04.067 に答える
2
-(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;
}
于 2013-07-14T21:35:51.033 に答える