9
votes

Remplacer les occurrences de nsnull dans la nsdiction nichée

Cette question est similaire à Cette question , cependant cette méthode ne fonctionne que sur le niveau de racine du dictionnaire.

Je cherche à remplacer tout événement de valeurs code> nsnull code> avec une chaîne vide, de sorte que je puisse enregistrer le dictionnaire complet vers un fichier de plis (si Je l'ajoute avec le fichier de Nsnull ne écrira pas). P>

Mon dictionnaire, cependant, a des dictionnaires imbriqués à l'intérieur. Comme ceci: p> xxx pré>

si j'utilise: p> xxx pré>

i obtenir quelque chose comme ceci: p>

"dictKeyName" = {
    innerStrKeyName = "This is a string in a dictionary";
    innerNullKeyName = ""; <-- this value has changed
    innerDictKeyName = {
        "innerDictStrKeyName" = "This is a string in a Dictionary in another Dictionary";
        "innerDictNullKeyName" = "<null>"; <-- this value hasn't changed
    };
};


6 commentaires

Aussi, vous devriez vraiment poster du code réel "" <- ce n'est ni un nstring ni un null


C'est la réponse réelle que je reçois. Je mesure un flux JSON et le dictionnaire est la réponse. Lorsque je le déconnecte, il sort comme "" et est reconnu dans la recherche et remplacer la boucle comme [Nsnull Null].


Le code que vous avez est de manipuler NSDictionary, donc lorsque vous analysez votre JSON appelez la méthode pour supprimer les Nsnulls.


Avez-vous des exemples de comment faire cela?


Avez-vous toujours un problème avec cela? L'une des réponses a-t-elle résolu le problème?


Nope, toujours les mêmes problèmes ...


8 Réponses :


0
votes

Ce code

@interface NSDictionary (JRAdditions)
    - (NSDictionary *) dictionaryByReplacingNullsWithStrings;
@end


2 commentaires

Je sais cela, mais les données sont dynamiques, je ne veux donc pas avoir à relâcher le code à chaque fois que le dictionnaire est mis à jour.


Vérifiez si l'objet est un dictionnaire et remplacez par le résultat de la méthode d'appelage.



17
votes

Une petite modification à la méthode peut le rendre récursif:

2012-09-01 08:30:16.210 Test[57731:c07] {
    "key1.1" = "string 1";
    "key1.2" = "<null>";
    "key1.3" =     {
        "key2.1" = "string 2";
        "key2.2" = "<null>";
    };
}
2012-09-01 08:30:16.212 Test[57731:c07] {
    "key1.1" = "string 1";
    "key1.2" = "";
    "key1.3" =     {
        "key2.1" = "string 2";
        "key2.2" = "";
    };


6 commentaires

Vraiment? J'ai ajouté un exemple d'utilisation avec sa sortie.


La dernière ligne est superflue; Il suffirait de remplacer remplacé; à la place.


Et si l'objet est Nsarray?


Comment gérer le json Strin imbriqué, voir dans ce message Stackoverflow.com/Questtions/48009583/...


J'utiliserais pour (Nstring * Touche dans [auto-alloncements]) Même si la mise en œuvre actuelle fonctionne - car elle est à la fois moins lisible, et vous devez creuser beaucoup pour savoir que l'énumération rapide sur NSDictionary énumérait les clés. (pourrait être des valeurs ou des paires ou autre chose.


De plus, il existe des mécanismes d'énumération plus rapides pour Nsdictionnaires, qui sont simultanés, et utilisent également des files d'antécédents, telles que [remplacées énumérablesKeysandObjecteBlock: ^ (Nstring * _nonnull Key, Nstring * _nonnull Valeur, BOOL * _Nonnull STOP) {if (valeur == [nsnull null]) [Self SetValue: @ "N / A" Forge: clé]; }];



0
votes

Essayez ceci:

@interface NSDictionary (JRAdditions)
 - (NSDictionary *) dictionaryByReplacingNullsWithStrings;
 -(NSDictionary *) nestedDictionaryByReplacingNullsWithStrings;
@end

@implementation NSDictionary (JRAdditions)

- (NSDictionary *) dictionaryByReplacingNullsWithStrings {

const NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary:self];
const id nul = [NSNull null];
const NSString *blank = @"";

for(NSString *key in replaced) {
    const id object = [self objectForKey:key];
    if(object == nul) {
        [replaced setObject:blank forKey:key];
    }
}
return [NSDictionary dictionaryWithDictionary:replaced];
}

-(NSDictionary *) nestedDictionaryByReplacingNullsWithStrings
{  
  const NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary:self];
  const id nul = [NSNull null];
  const NSString *blank = @"";
  for(id *item in replaced) {
    const id object = [self objectForKey:key];
    if([object isKindofClass:[NSDictionary class]])
    {
       NSDictionary *innerDict = object;
       [replaced setObject:[innerDict dictionaryByReplacingNullsWithStrings] forKey:key];

    }
    else
    {
     if(object == nul) {
        [replaced setObject:blank forKey:key];
     }
    }
 }
 return [NSDictionary dictionaryWithDictionary:replaced];  
}


0 commentaires

10
votes

Cela fonctionne pour moi, j'ai utilisé une boucle imbriquée pour remplacer tout NULL avec nul dans tout le dictionnaire, y compris NSARRAY.

- (NSDictionary *) dictionaryByReplacingNullsWithNil:(NSDictionary*)sourceDictionary {

    NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary:sourceDictionary];
    const id nul = [NSNull null];

    for(NSString *key in replaced) {
        const id object = [sourceDictionary objectForKey:key];
        if(object == nul) {
            [replaced setValue:nil forKey:key];
        }
    }
    return [NSDictionary dictionaryWithDictionary:replaced];
}

-(NSDictionary *) nestedDictionaryByReplacingNullsWithNil:(NSDictionary*)sourceDictionary
{
    NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary:sourceDictionary];
    const id nul = [NSNull null];
    const NSString *blank = @"";
    [sourceDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
        object = [sourceDictionary objectForKey:key];
        if([object isKindOfClass:[NSDictionary class]])
        {
            NSDictionary *innerDict = object;
            [replaced setObject:[self nestedDictionaryByReplacingNullsWithNil:innerDict] forKey:key];

        }
        else if([object isKindOfClass:[NSArray class]]){
            NSMutableArray *nullFreeRecords = [NSMutableArray array];
            for (id record in object) {

                if([record isKindOfClass:[NSDictionary class]])
                {
                    NSDictionary *nullFreeRecord = [self nestedDictionaryByReplacingNullsWithNil:record];
                    [nullFreeRecords addObject:nullFreeRecord];
                }
            }
            [replaced setObject:nullFreeRecords forKey:key];
        }
        else
        {
            if(object == nul) {
                [replaced setObject:blank forKey:key];
            }
        }
    }];

    return [NSDictionary dictionaryWithDictionary:replaced];  
}


3 commentaires

Cette mise en œuvre est très utile que la cause acceptée qui prend des tableaux en compte


Cette implémentation ne prendra pas en compte les tableaux, qui contiennent des données non dictionnaires (par exemple des chaînes ou des tableaux). Il retournera un tableau vide


Excusez-moi ... mais [Somemutableddictionner SetValue: Nil Forkey @ "Sommet an"] ne présente pas de nul dans le dictionnaire - qui s'écraserait immédiatement. Au lieu de cela, il supprime complètement la paire de la clé / de la valeur. Je ne suis pas sûr que cela soit bon pour répondre aux besoins de l'OP



0
votes

Cette solution fonctionne avec des tableaux et des dictionnaires, ainsi que pour des tableaux ni des dictionnaires imbriqués, etc. (récursivement).

- (NSDictionary *)writableDictionary:(NSDictionary *)dictionary
{
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary];

    for (id key in mutableDictionary.allKeys)
    {
        id value = mutableDictionary[key];
        mutableDictionary[key] = [self writableValue:value];
    }

    return mutableDictionary;
}

- (NSArray *)writableArray:(NSArray *)array
{
    NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];

    for (int i = 0; i < mutableArray.count; ++i)
    {
        id value = mutableArray[i];
        mutableArray[i] = [self writableValue:value];
    }

    return mutableArray;
}

- (id)writableValue:(id)value
{
    if ([value isKindOfClass:[NSNull class]])
    {
        value = @"";
    }
    else if ([value isKindOfClass:[NSDictionary class]])
    {
        value = [self writableDictionary:value];
    }
    else if ([value isKindOfClass:[NSArray class]])
    {
        value = [self writableArray:value];
    }
    return value;
}


0 commentaires

0
votes

Les réponses mentionnées ci-dessus ne traitent pas de la situation si vous avez une matrimonie dans votre dictionnaire. Vérifiez ceci out

+(NSMutableDictionary*)getValuesWithOutNull:(NSDictionary          
     *)yourDictionary{
       NSMutableDictionary *replaced = [NSMutableDictionary 
     dictionaryWithDictionary: yourDictionary];
      id nul = [NSNull null];
      NSString *blank = @"";

for (NSString *key in yourDictionary) {
    const id object = [yourDictionary objectForKey: key];
    if (object == nul) {
        [replaced setObject: blank forKey: key];
    }
    else if ([object isKindOfClass: [NSDictionary class]]) {
        [replaced setObject:[self getValuesWithOutNull:object] 
forKey:key];
    }
    else if([object isKindOfClass: [NSArray class]])
    {
        NSMutableArray *array  = [NSMutableArray 
arrayWithArray:object];
        for(int i = 0 ;i < array.count;i++)
        {
            NSDictionary *dict = [array objectAtIndex:i];
            [array replaceObjectAtIndex:i withObject:[self 
  getValuesWithOutNull:dict]];
        }
        [replaced setObject:array forKey:key];
    }
 }
  return  replaced;

}


0 commentaires

2
votes

Si quiconque a besoin de cela pour Swift 1.2, voici le snippet: xxx


2 commentaires

Fonctionne, mais vous avez oublié la "Key" [Key] = DESTARRAY à la fin du cycle


@Danilo, merci pour le commentaire, j'ai édité l'extrait



2
votes

La méthode suivante fonctionne parfaitement pour tout nombre d'arrars nichés de dictionnaire: xxx

J'ai utilisé au-delà de la méthode modifiée selon mes fonctionnalités requises:

// Méthode d'appel < / p> xxx


0 commentaires