【问题标题】:How to iterate a multidimensional json_decoded object in Perl to create a new json object?如何在 Perl 中迭代多维 json_decoded 对象以创建新的 json 对象?
【发布时间】:2013-07-16 20:32:47
【问题描述】:

我正在尝试在 Perl 中重新创建一个 php 进程,但运气不佳(我不太了解 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

然后我在尝试循环时收到“Not an ARRAY reference”。

然后我尝试这样的事情并没有得到任何结果或错误:

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 中重新创建相同的结果?非常感谢您的帮助。

【问题讨论】:

  • 你试过了吗?
  • @HydraIO - 是的,我有而且我无法重新创建它,因此在这里发帖寻求帮助。我正在使用 JSON 模块,我已经解码了 json 并尝试遍历数组、数组哈希,但我对 Perl 循环的了解不够,无法像我在 php 中那样做。
  • @daxim - 我已经用我的尝试更新了我的问题。希望它能证明我哪里出错了。

标签: php json perl multidimensional-array


【解决方案1】:

好吧,你并没有真正出错;它只是尽可能愚蠢的 JSON 格式。 JSON 是键的散列(排序后的数字字符串),映射到另一个散列级别,具有键 namevalue

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

(此数据可能应该编码为[{"someKey": "someValue"}, {"anotherKey": "anotherValue"}]。)

所以我们要做的是循环遍历外部哈希的数字排序键:

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

在该循环中,我们循环遍历哈希值的键/值。相反,我们只选择键 namevalue 的值:

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

并打印出来:

say "key: $key, value: $value";

【讨论】:

  • 感谢您的回复。我知道这是一个愚蠢的 json 结构。我必须使用它 atm :( 我尝试了您的代码:my %records = %{ decode_json($json_text) }; for my $index (sort { $a &lt;=&gt; $b } keys %records) { my %record; my $record_value = $record{$index}; my ($key, $value) = @$record_value{qw/key value/}; print "key: $key, value: $value"; } 但我没有得到任何数据值。只是很多这些 Use uninitialized value in concatenation (.) or string at json_test.cgi line 16. and key: ,值:键:,值:键:,值:键:,值:键:,值:键:,值:键:等
  • @user2535949 非常抱歉,有一个错字:它是$records{$index}s。哦,你会想要 print "key: $key, value: $value\n" 换行符。
  • 感谢您的更正!我们就快到了。我可以正确获取值,但 $key 打印为空白?会不会和哈希切片有关?
  • @user2535949 是的,它是@$record_value{qw/name value/}。我忘了关键字段被命名为name
  • 太好了,就是这样 :) 我现在应该能够从这些值重新创建新的 json。非常感谢。
猜你喜欢
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2019-07-21
  • 1970-01-01
相关资源
最近更新 更多