Как перебрать многомерный объект json_decoded в Perl, чтобы создать новый объект json?

Я пытаюсь воссоздать процесс php в Perl, и мне не очень повезло (я мало знаю Perl).

Это мой php-код:

$json = '{"0":{"name":"action","value":"none"},"1":{"name":"additionalTraining","value":"modulesRevisited"},"2":{"name":"additionalTrainingComments","value":""},"3":{"name":"additionalTraining","value":"moduleReporting"},"4":{"name":"additionalTrainingComments","value":""},"5":{"name":"additionalTrainingComments","value":""},"6":{"name":"anotherValue","value":""},"7":{"name":"1359436206","value":""},"8":{"name":"1359436207","value":""},"48":{"name":"actionId","value":""},"49":{"name":"multiSelect","value":"second"},"50":{"name":"multiSelect","value":"third"},"51":{"name":"radio","value":"1"},"52":{"name":"svgs","value":{"0":{"id":"drawing"},"1":{"id":"drawing"}}}}';
$decoded = json_decode($json,true);
$clean = array();
foreach($decoded as $Obj => $array){
    if(array_key_exists($array['name'], $clean))
    {
        if(!is_array($clean[$array['name']]))
        {
            $value = $clean[$array['name']];
            $clean[$array['name']] = array($value,$array['value']);
        }
        else
        {
            array_push($clean[$array['name']], $array['value']);
        }
    }
    else
    {
        $clean[$array['name']]=$array['value'];
    }
}
 echo json_encode($clean);

ОБНОВЛЕНИЕ: вот что я пробовал в Perl и постоянно натыкаюсь на стены:

use JSON;
use Data::Dumper;
use warnings;
use strict;
my @records = decode_json($json_text); 
foreach my $element (@records)
{
      print "$element\n";
}

Я получаю hashref. Поэтому я пытаюсь изменить первую строку на:

my @records = @{ decode_json($json_text) }; #dereference function as it returns an arrayref, not a list

Затем я получаю «Не ссылка на МАССИВ» при попытке выполнить цикл.

Затем я пробую что-то вроде этого и не получаю никаких результатов или ошибок:

my $records = decode_json($json_text); 
my $i = 0;
my @records;
foreach my $entry (@{$records[0]}) {
    my %listHash = %{$entry};
    my $key;
    my $value;
    $i++;
    while(($key, $value) = each(%listHash)) {   
        my $key;
        my $value;
        print "${key}_$i, $value\n";
    }
}

Затем я пытаюсь объединить части всех из них, чтобы получить результат, который мне нужен, и самое близкое, к чему я пришел, это:

my %records = %{ decode_json($json_text) }; 
while ( my ($key, $value) = each %records )
{
  my $records;
  #print "key: $key, value: $records{$key}\n";
  while ( my ($key, $value) = each %{$value} )
  {
    print "key: $key, value: $value\n";
  }
}

Но это дает мне вывод так:

key: name, value: anotherValue
key: value, value: third
key: name, value: multiSelect
key: value, value: moduleReporting

тогда как мне нужен вывод, например

key: anotherValue, value: third
key: multiSelect, value: moduleReporting

Где я ошибаюсь?

Как я могу воссоздать тот же результат в Perl? Ваша помощь очень ценится.


person user2535949    schedule 18.07.2013    source источник
comment
ты что-нибудь пробовал?   -  person Hydra IO    schedule 18.07.2013
comment
@HydraIO - Да, у меня есть, и я не смог воссоздать его, поэтому отправляю сюда за помощью. Я использую модуль JSON, я декодировал json и пытался перебрать массив, хэши массива, но я недостаточно знаю о циклах Perl, чтобы сделать это так, как я делаю это в php.   -  person user2535949    schedule 18.07.2013
comment
@daxim - я обновил свой вопрос тем, что пробовал. Надеюсь, это демонстрирует, где я иду не так.   -  person user2535949    schedule 19.07.2013


Ответы (1)


Что ж, на самом деле вы не ошибетесь; это просто формат JSON, который настолько глуп, насколько это возможно. JSON представляет собой хэш ключей (отсортированные числовые строки), которые сопоставляются с другим уровнем хэшей, имеющими ключи name и value:

{
  "0": {"name": "someKey",    "value": "someValue"},
  "1": {"name": "anotherKey", "value": "anotherValue"}
}

(Эти данные, вероятно, должны быть закодированы как [{"someKey": "someValue"}, {"anotherKey": "anotherValue"}].)

Итак, что мы сделаем, так это переберем численно отсортированные ключи для внешнего хэша:

for my $index (sort { $a <=> $b } keys %records) { ... }

Внутри этого цикла мы не перебираем ключи/значения хеш-значений. Вместо этого мы просто выбираем значения ключей name и value:

my $record_value = $records{$index};
my ($key, $value) = @$record_value{qw/name value/};   # a "hash slice"

и распечатайте их:

say "key: $key, value: $value";
person amon    schedule 18.07.2013
comment
Благодарю за ваш ответ. Я знаю, что это глупая структура json. Я должен работать с этим банкоматом :( Я попробовал ваш код: my %records = %{ decode_json($json_text) }; for my $index (sort { $a <=> $b } keys %records) { my %record; my $record_value = $record{$index}; my ($key, $value) = @$record_value{qw/key value/}; print "key: $key, value: $value"; }, но я не получаю значений данных. Просто много из них Использование неинициализированного значения в конкатенации (.) или строка в json_test.cgi строка 16. и ключ: , значение: ключ: , значение: ключ: , значение: ключ: , значение: ключ: , значение: ключ: , значение: ключ: и т. д. - person user2535949; 19.07.2013
comment
@user2535949 user2535949 Мне очень жаль, была опечатка: это $records{$index} с s. О, и вам понадобится print "key: $key, value: $value\n" с новой строкой. - person amon; 19.07.2013
comment
Спасибо за эту поправку! Мы почти на месте. Я могу правильно получить значения, но ключ $ печатается пустым? Может ли это быть связано с ломтиком хэша? - person user2535949; 19.07.2013
comment
@ user2535949 Да, это @$record_value{qw/name value/}. Я забыл, что ключевое поле называется name. - person amon; 19.07.2013
comment
Отлично, вот и все :) Теперь я смогу воссоздать новый json из этих значений. Спасибо большое. - person user2535949; 22.07.2013