Difficulté avec NSdictionnary

Bonjour ami(es) développeur,


 


Un exercice m'a été donné en PHP, cela consiste à  trouvé le nombre d'occurence et a l'incrémenter par index donné.


 


 A.C : 1


 A.B : 1


 A.B.D : 3


 A.B.C : 1


 A2/B/C : 4


 


 result :


 A : 6


 A/B : 5


 A/B/C : 1


 A/B/D : 3


 A/C : 2


 A2 : 4


 A2/B : 4 


 A2/B/C : 4


 


 


Mon code PHP est fonctionnel mais j'aurai voulu le faire en Objective-C et j'ai un peu de mal depuis quelques jours, je vous montre mes codes:

 



<?php
#PHP CODE

$str=" A.C : 1\n A.B : 1\n A.B.D : 3\n A.B.C : 1\n A2/B/C : 4\n";
$dictionnaire = array();
$data = explode("\n", $str);
$data = array_filter($data);
var_dump($data);
foreach ($data as $d)
{
$tab = explode(':', $d);
$tmp = explode('.', $tab[0]);
foreach ($tmp as $t)
{
$dictionnaire[$t] += $tab[1];
}
}

var_dump($dictionnaire);
?>


Code Objective-C



NSString *myFile = @A.C :1\n A.B :1\n A.B.D :3\n A.B.C :1\n A2/B/C :4\n;
NSArray *mySplit = [myFile componentsSeparatedByString:@\n];
for (NSString *ligne in mySplit)
{
NSArray *splitLign = [ligne componentsSeparatedByString:@:];
NSArray *tempSplit = [splitLign[0] componentsSeparatedByString:@/];
NSMutableDictionary *dico;
for (???????)
{
???????????????????
}

}


J'ai essayé plein de truc regardé sur stackOver mais je n'est pas trouvé, je suis sur que j'ai un truc stupide ou une mauvaise utilisation de mon dico.

 

Merci bien,

Cordialement.

 

Réponses

  • Pas vraiment compris ce que tu dois faire... Peux-tu être un peu plus précis ? Par exemple un petit organigramme, çà  permettra de t'aider éventuellement... Ou alors dis ce que tu ne comprends pas dans l'utilisation des NSDictionary, car il semblerait que ce soit ton problème. Tu peux aussi donner le code que tu as essayé et l'erreur obtenue. 


    Sinon, la doc est là  aussi.


  • LouLou Membre
    décembre 2014 modifié #3

    J'ai essayé ça, je pense que c'est correct :



    - (BOOL)containsKey: (NSString *)key inDict: (NSDictionary*) dict {
    BOOL retVal = 0;
    NSArray *allKeys = [dict allKeys];
    NSLog(@%@ : ", allKeys);
    retVal = [allKeys containsObject:key];
    NSLog(@retVal %d , retVal);
    return retVal;
    }

    - (void)viewDidLoad {
    [super viewDidLoad];

    NSString *myString = @A.C :1\n A.B :2\n A.B.D :3\n A.B.C :1\n A2/B/C :4;
    myString = [myString stringByReplacingOccurrencesOfString:@ withString:@""];//on enleve les espaces
    NSArray *allLines = [myString componentsSeparatedByString:@\n];
    NSMutableDictionary *result = [[NSMutableDictionary alloc] init];

    for (NSString *eachLine in allLines)
    {
    NSArray *eachItem = [eachLine componentsSeparatedByString:@:];
    NSArray *letters = [eachItem[0] componentsSeparatedByString:@.];//A.B

    for (int i=0; i<letters.count; i++){
    NSLog(@letters[;i] : %@ ", [NSString stringWithFormat:@%@", letters[i]] );
    //s'il n'existe pas dans le dictionnaire, on l'ajoute, et on passe a l'iteration suivante
    if ( [self containsKey:letters[i] inDict:result] == 0 ) {
    int value = [eachItem[1] intValue];
    [result setObject:@(value) forKey:letters[i]];
    NSLog(@objectForKey %@ : %@", letters[i], [result objectForKey:letters[i]]);
    }
    else {
    //sinon, on rajoute le chiffre au nombre deja existant
    int value = [[result objectForKey:letters[i]] intValue];
    value += [eachItem[1] intValue];
    NSLog(@incremente value : %d, value);
    [result setObject:@(value) forKey:letters[i]];
    }
    }
    }
    }

    Pour trouver un élément dans un NSString, voilà  une fonction regex qui pourra peut-être te servir, il faut penser à  mettre deux slash inversés pour les caractères spéciaux : "\\." (deux slashs inversés suivi du point)



    -(BOOL) containsPoint:(NSString*) string{
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression
    regularExpressionWithPattern:@\\. options:0 error:&error];
    if ([regex matchesInString:string options:0 range:NSMakeRange(0, [string length]) ]){
    NSLog(@%@ contient bien un . ", string);
    return TRUE;
    }
    else return FALSE;
    }

  • Ok oui effectivement ça marche !!! je trouve cela un peu lourd comparé avec la version php, décidément l'objective-C va me donner du file à  retord !!!! en tout cas GG ton algo marche, je n'avais pas pensé à  le faire comme cela !!!!


     


    Rhhho quand tu set un object dans ton dico tu met la value dans un @(), moi je le mettais sans, d'où plusieurs erreurs (faut vraiment que j'apprenne à  lire la doc !!!!


     


    Merci en tout cas.


    Cordialement.


     


    Je ne clos pas le sujet je voudrai pouvoir vous montrez le code que j'aurai fait au final.


  • AliGatorAliGator Membre, Modérateur
    décembre 2014 modifié #5
    J'ai pas du tout suivi le sujet ni l'algo, mais si le code de Lou fonctionne, je me permettrais de le réécrire (sans chercher à  le comprendre) pour le simplifier ainsi, te montrant qu'il peut être moins impressionnant (car tu sembles penser que c'est beaucoup + lourd que la version PHP, alors qu'en pratique je ne pense pas tant que ça, c'est plutôt les NSLog et l'utilisation d'une méthode supplémentaire " pourtant inutile " "containsKey:inDict:" qui te donne cette impression)

    NSString *myString = @A.C :1\nA.B :2\nA.B.D :3\nA.B.C :1\nA2/B/C :4;
    NSArray *allLines = [myString componentsSeparatedByString:@\n];
    NSMutableDictionary *result = [NSMutableDictionary new];

    for (NSString *eachLine in allLines)
    {
    NSArray *eachItem = [eachLine componentsSeparatedByString:@ :];
    NSArray *letters = [eachItem[0] componentsSeparatedByString:@.];//A.B

    for (NSString* letter in letters) {
    if ( result[letter] == nil ) {
    result[letter] = eachItem[1];
    } else {
    int value = [result[letter] intValue];
    value += [eachItem[1] intValue];
    result[letter] = @(value);
    }
    }
    }
    Ce que j'ai fait :

    1) Supprimé la méthode inutile "containsKey:inDict:", on peut faire cette vérification simplement via "dict[key] != nil"

    2) Supprimé les commentaires et NSLog qui donnaient des bonnes explications mais donnaient aussi du volume de ligne de code pouvant te donner l'impression que le code dans son ensemble était complexe

    3) Utilisé la Modern ObjC syntax ("dict[key] = value" est plus simple et lisible que "[dict setValue:value forKey:key]" et moins impressionnant

    4) Evité d'extraire (dans le "if") la intValue du NSNumber juste pour la reconvertir en NSNumber dans la foulée.


    Note qu'on peut même directement se passer du "if", puisque si la clé n'existe pas, la intValue de sa valeur (qui est donc nil) vaut 0, donc faire l'addition avec zéro ne change rien au résultat. Ce qui simplifie encore le code en :

    NSString *myString = @A.C :1\nA.B :2\nA.B.D :3\nA.B.C :1\nA2/B/C :4;
    NSArray *allLines = [myString componentsSeparatedByString:@\n];

    NSMutableDictionary *result = [NSMutableDictionary new];
    for (NSString *eachLine in allLines)
    {
    NSArray *eachItem = [eachLine componentsSeparatedByString:@ :];
    NSArray *letters = [eachItem[0] componentsSeparatedByString:@.];//A.B

    for (NSString* letter in letters) {
    int value = [result[letter] intValue];
    value += [eachItem[1] intValue];
    result[letter] = @(value);
    }
    }
    Après je le répète je n'ai fait que reprendre le code de Lou et le réécrire de façon plus compacte, je n'ai pas analysé son algo pour voir si cela correspondait à  ce que tu attendais (je ne me suis pas penché sur ce problème).
  • Exact.


     


    Je crois que si tu testes, c'est  "letter" plutôt que "letters" dans le for :



    int value = [result[letter] intValue];//letter

    et cette ligne pour enlever les espaces est importante je pense :



    myString = [myString stringByReplacingOccurrencesOfString:@ withString:@""];

    sinon les keys sont parfois avec un espace, donc les keys sont différentes et n'incrémente pas les keys déjà  existantes.


     


    Voilà  un petit lien qui devrait te servir pour les "literals" ;) : lien


  • Bonjour,


     


    En effet Alligator ta méthode est moins lourde, j'était parti sur cette méthode mais c'était ma syntaxe qui péchait "la Modern ObjC syntax "dict[key] = value" ne passait pas , je vous remercie pour votre aide apporté. 


     


    Merci encore.


    Cordialement.


Connectez-vous ou Inscrivez-vous pour répondre.