анализировать значение из словаря/списка

У меня есть словарь/список 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; имя_узла = количество;

Я не уверен, как получить доступ к этой части.

Пожалуйста помоги.
}

На самом деле вот что я получаю во время альтернативных запусков;

Вывод описания nodeChildArray: {type = mutable dict, count = 2, entry => 0 : {contents = "nodeName"} = {contents = "Signature"} 1 : {contents = "nodeContent"} = {contents = "- 1507"} }

Вывод описания nodeChildArray: {type = mutable dict, count = 2, entry => 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
Эй, Томсон... Большое спасибо... ответ, кажется, совпадает с тем, что я ищу... Но только один вопрос; могу ли я использовать функцию для возврата значения на основе того, что передается для подписи, например. если я хочу, чтобы значение узла Amount для узла Signature имело -873), т.е. оно должно вернуть мне 1501042000, т.е. если я передам подпись -873 функции, она должна вернуть мне 1501042000 - person copenndthagen; 05.02.2011
comment
@Thomson Comer: Кажется, есть проблема с типом nodeChildArray. На самом деле кажется, что он возвращает dict, а не массив. Я только что проверил в отладчике, и в результате я все еще не получаю правильный результат. - person copenndthagen; 05.02.2011
comment
хмтур, извини, я вижу, где была моя ошибка. Я обновил ответ, и теперь он должен делать то, что вы просите. Вы получите обратно 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 = [сам разбор баланса: баланс_знак_дикт]; 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 часов (из-за некоторого расширения API) и вернуться к вам. Но опять же .. огромное спасибо за всю помощь, которую вы оказали. - person copenndthagen; 05.02.2011
comment
Хотя мне нужно подождать некоторое время, чтобы протестировать код, мне просто нужно быстрое подтверждение, проходящее через ваш код. В основном строка NSArray* nodeChildArray = [nodeDict objectForKey:@nodeChildArray]; Я надеюсь, что он на самом деле возвращает массив, а не словарь, как это было раньше. Я не уверен, почему это произошло. Опять же, мне нужно подождать и проверить это. - person copenndthagen; 05.02.2011
comment
hmthur Я добавил много обсуждений того, как я сделал parseBalance:, и небольшое изменение в сообщении. - person Thomson Comer; 06.02.2011
comment
ТЫ ДЕЙСТВИТЕЛЬНО ПОТРЯСАЮЩИЙ THOMSON Я НЕ МОГУ ПОЛУЧИТЬ ОПИСАНИЯ ЛУЧШЕГО, ЧЕМ ТО, ЧТО ВЫ ДАЛИ... ДАЖЕ ИЗ ДОКУМЕНТАЦИИ Apple !! 7 ЗВЕЗД ВАМ !!!! - person copenndthagen; 06.02.2011