анализирайте стойност от речник/списък

Имам речник/списък balance_sign_dict, от който трябва да извлека 2 стойности въз основа на условие. Изходният XML за това е;

<Value>
<Signature>-873</Signature>
<Amount>1501042000</Amount>
</Value>

Искам да анализирам данни от dict, показан по-долу; Бихте ли ми казали как да анализирам условни данни (напр. ако искам стойността на възел „Сума“ за възел „Подпис“ да има -873), т.е. трябва да ми върне 1501042000

Искам общ начин за анализиране на стойностите от речника по-долу.

Отпечатване на описание на balance_sign_dict:

(
        {
        nodeChildArray =         (
                        {
                nodeContent = "-873";
                nodeName = Signature;
            },
                        {
                nodeContent = 1501042000;
                nodeName = Amount;
            }
        );
        nodeName = Value;
    },
        {
        nodeChildArray =         (
                        {
                nodeContent = "-1228";
                nodeName = Signature;
            },
                        {
                nodeContent = 428586000;
                nodeName = Amount;
            }
        );
        nodeName = Value;
    },
        {
        nodeChildArray =         (
                        {
                nodeContent = "-1140";
                nodeName = Signature;
            },
                        {
                nodeContent = 79370000;
                nodeName = Amount;
            }
        );
        nodeName = Value;
    },

Ето какво опитвам сега;

for (NSDictionary *valueNode in balance_sign_dict){
            for (NSArray *nodeChildArray in [valueNode objectForKey:@"nodeChildArray"]){
                NSString *tmpNodeName = [nodeChildArray objectAtIndex:1];
                NSDictionary *tmpD = [valueNode objectAtIndex:1];


                if ([tmpNodeName isEqualToString:@"Signature"]) {
                    tmpSignVal = [nodeChildArray objectAtIndex:0];
                    if ([tmpSignVal isEqualToString:@"-873"]) {
                        tmpSignAmt = [nodeChildArray objectAtIndex:1];
                    }
                }

Но по някаква причина втората част на nodeChildArray се премахва... т.е. nodeContent = 1501042000; nodeName = Сума;

Не съм сигурен как да получа достъп до тази част.

Моля помогнете.
}

Всъщност ето какво получавам по време на редуване;

Отпечатване на описание на nodeChildArray: {type = mutable dict, count = 2, entries => 0 : {contents = "nodeName"} = {contents = "Signature"} 1 : {contents = "nodeContent"} = {contents = "- 1507"} }

Отпечатване на описание на nodeChildArray: {type = mutable dict, count = 2, entries => 0 : {contents = "nodeName"} = {contents = "Amount"} 1 : {contents = "nodeContent"} = {contents = "631000 "}}

Как да получа стойността на сумата за съответстваща стойност на подписа?


person copenndthagen    schedule 04.02.2011    source източник


Отговори (1)


NSArray и NSDictionary са най-добрите контейнерни класове, които познавам на всеки език, с който имам опит. NSDictionary може да съхранява всеки обект или примитив, включително NSArray, и обратно. Когато казвам речник, произволно имам предвид двата класа.

Когато изведете описанието на произволен речник (което е толкова просто, колкото NSLog(@"%@",myDict);, цялото съдържание на речника се показва като XML (или може би по-точно JSON) документ. Лесно е да разгледате съдържанието на описанието на речника, за да определи какво се съдържа вътре () обозначава NSArray, а {} обозначава NSDictionary.

// this is the beginning of an array.
(
        // this is the beginning of index 0 of the array, an `NSDictionary`
        {
        // objectForKey:@"nodeChildArray"] isKindOfClass:[NSArray class]]
        nodeChildArray =         ( // inside nodeChildArray is another array
                        { // index 0 of array is a dictionary with two keys
                // objectForKey:@"nodeContent" == @"-873"
                nodeContent = "-873";
                // objectForKey:@"nodeName" == @"Signature"
                nodeName = Signature;
            }, // end of index 0
                        { // index 1 of array
                nodeContent = 1501042000;
                nodeName = Amount;
            } // end of index 1
        ); // end of nodeChildArray, an NSArray stored at objectForKey:@"nodeChildArray"
        // this is the only other element in the dictionary, a string
        // objectForKey:@"nodeName"] isKindOfClass:[NSString class]]
        nodeName = Value;
    }, // end of the dictionary containing nodeChildArray and nodeName
        { // objectAtIndex:1
        nodeChildArray =         (
                        {
                nodeContent = "-1228";
                nodeName = Signature;
            },
                        {
                nodeContent = 428586000;
                nodeName = Amount;
            }
        );
        nodeName = Value;
    },
        { // objectAtIndex:2
        nodeChildArray =         (
                        {
                nodeContent = "-1140";
                nodeName = Signature;
            },
                        {
                nodeContent = 79370000;
                nodeName = Amount;
            }
        );
        nodeName = Value;
    },
);

Така че можете да видите, като погледнете вашия NSDictionary изход за отстраняване на грешки, че това всъщност е NSArray. Редът на структурите е NSArray->NSDictionary->NSArray->NSString <--> [[[[NSArray objectAtIndex:i] NSDictionary objectForKey:@"nodeChildArray"] NSArray objectAtIndex:j] NSDictionary objectForKey:@"nodeContent"], накрая връща NSString. Използвайте това като най-нов код - в последната версия на кода подадох balance_sign_dict като NSDictionary. Това може дори да е проработило! Но е много по-добра форма да изложите аргумента правилно. Ако не знаете дали вашият речник ще започва с NSArray или NSDictionary, можете да го преобразувате като id и да проверите типа му с [theIdObject isKindOfClass:[{NSArray,NSDictionary} class]]. Не използвайте {} и изберете едно от двете в кода си.

-(NSDictionary*)parseBalance:(NSArray*)balance_sign_dict
{
  NSMutableDictionary* theResults = [NSMutableDictionary dictionary];
  for( NSDictionary* nodeDict in balance_sign_dict )
  {
    NSArray* nodeChildArray = [nodeDict objectForKey:@"nodeChildArray"];
    [theResults addObject:[[nodeChildArray objectAtIndex:1] objectForKey:@"nodeContent"] forKey:[[nodeChildArray objectAtIndex:0] objectForKey:@"nodeContent"]];
  }
  return theResults;
}
person Thomson Comer    schedule 04.02.2011
comment
Хей Thomson...Благодаря много...отговорът изглежда е в съответствие с това, което търся...Но само един въпрос; мога ли да използвам функцията, за да върна стойността въз основа на това, което е предадено за подпис, напр. ако искам стойността на възела Amount за възела Signature да има -873), т.е. трябва да ми върне 1501042000, т.е. ако предам подпис -873 на функцията, тя трябва да ми върне 1501042000 - person copenndthagen; 05.02.2011
comment
@Thomson Comer: Изглежда има някакъв проблем с типа на nodeChildArray. Всъщност изглежда, че връща dict, а не масив. Току-що проверих в програмата за отстраняване на грешки и в резултат на това все още не получавам правилния резултат. - person copenndthagen; 05.02.2011
comment
hmthur, съжалявам, виждам къде е грешката ми. Актуализирах отговора и сега трябва да прави това, което питате. Ще получите обратно NSDictionary, където казването на [myDict objectForKey:@-873] ще върне 1501042000 за всички елементи в balance_sign_dict. - person Thomson Comer; 05.02.2011
comment
@Thomson Comer: Няма нужда да се извинявате. Вместо това трябва да ви благодаря за цялата помощ, която оказахте. Само за да потвърдя, ще добавя функцията parseBalance: която сте актуализирали и ще я извикам с помощта на; NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init]; NSString *tmpStr; myDict = [self parseBalance:balance_sign_dict]; tmpStr = [myDict objectForKey:@-873]; Трябва ли да предам self.balance_sign_dict или само balance_sign_dict? Бихте ли могли да потвърдите дали сега подходът ми е правилен? - person copenndthagen; 05.02.2011
comment
Както написахте, myDict всъщност ще стане изтичане на памет, тъй като го разпределите и след това незабавно го презапишете с върнатия резултат от parseBalance:. Вместо това просто кажете NSMutableDictionary *myDict = [self parseBalance:balance_sign_dict];. Ако трябва да съхраните myDict в членска променлива, която съществува, когато излезете от текущия обхват, ще трябва да го запазите. Не мисля, че трябва да предавате self.balance_sign_dict. Докато @property не е зададено на readonly, не мисля, че има разлика между self.balance_sign_dict и balance_sign_dict, когато четете стойността. - person Thomson Comer; 05.02.2011
comment
добре..благодаря много за информацията...ще мога да внедря даденото от вас решение след около 12 часа (поради някаква имитация на ext api) и ще се свържа с вас. Но отново..благодаря много за цялата помощ, която предоставихте. - person copenndthagen; 05.02.2011
comment
Въпреки че трябва да изчакам известно време, за да тествам кода, просто ми трябваше бързо потвърждение, преминавайки през вашия код. По принцип редът NSArray* nodeChildArray = [nodeDict objectForKey:@nodeChildArray]; Надявам се, че действително връща масив, а не dict, както се случваше преди. Не съм сигурен защо това се случва. Отново трябва да изчакам и да го тествам. - person copenndthagen; 05.02.2011
comment
hmthur Добавих много дискусии за това как направих parseBalance: и малка промяна в съобщението. - person Thomson Comer; 06.02.2011
comment
ВИЕ НАИСТИНА РАЗТЪРЧАТЕ THOMSON НЕ БЯХ МОГАЛ ДА ПОЛУЧА ПО-ДОБРО ОПИСАНИЕ ОТ ТОВА, КОЕТО СТЕ ДАЛИ... ДОРИ ОТ ДОКУМЕНТАЦИЯТА НА APPLE !! 7-ЗВЕЗДИ ЗА ВАС !!!! - person copenndthagen; 06.02.2011