Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!

I need to add values into a hash to create a JSON file. Is there a better way to do this. Here is the code I am trying:
#!/usr/bin/perl use strict; use warnings; use Data::Dump 'pp'; use Data::Dumper; use JSON; my %data; foreach my $number (@{ $names }) { $data{name} = $claim->{"n_names"}; $data{address} = $claim->{"n_add"}; $data{phone} = $claim->{"n_phone"}; $data{email} = $claim->{"n_email"} || ''; push \%data, $data{name}, $data{address}, $data{phone}, $data{email +}; } my $json = encode_json \%data; print Dumper $json;
Thanks for helping!

Replies are listed 'Best First'.
Re: Push values into a hash
by Corion (Patriarch) on Jul 25, 2016 at 14:44 UTC

    What is that line doing? How does your code behave differently when you leave it out?

    push \%data, $data{name}, $data{address}, $data{phone}, $data{emai +l};

    Where is $number used? What is $claim?

    You could make your code a bit more data-driven by doing the assignment through a list of pairs in a loop:

    my %field_name_mapping = ( n_names => 'name', n_add => 'address', n_phone => 'phone', n_email => 'email', ); ... for my $source (sort keys %field_name_mapping) { my $target = $field_name_mapping{ $source }; $data{ $target } = $claim->{$source}; };
      This should be this:
      $data{name} = $number->{"n_names"}; $data{address} = $number->{"n_add"}; $data{phone} = $number->{"n_phone"}; $data{email} = $number->{"n_email"} || '';

        You keep trying to push \%data. What is that supposed to accomplish?

        I don't understand what you're trying to do here. A hash always consists of a key and a value. You at best have a value here, never mind the syntax.

        Maybe you want to use a real array, @data instead of a hash?

        I think in addition to your code, you should also show what data structure you want at the end.

      Hi, is a better sample of what I am trying to do:
      #!/usr/bin/perl use strict; use warnings; use Data::Dump 'pp'; use Data::Dumper; use JSON; my %data; foreach my $line (<DATA>) { chomp($line); my ($names, $add, $phone, $email) = split/,/, $line; push \%data, { name => $data{name}, address => $data{address}, pho +ne => $data{phone}, email => $data{email} }; } my $json = encode_json \%data; print Dumper $json; __DATA__ Joe, Main Street, 346 20274, test1@test.com Mary, Central Road, 02615128, test2@test.com Lou, Cannal St, 612262297692848, test3@test.com Carl, Sout St, 3268022049187, test4@test.com
        I suspect you want an array, not a hash (push is an array operation) i.e.
        my @rows; ... # rest of code push @rows, { ... }; ... my $json = encode_json \@rows;
        update: Renamed variable
        And what do you want the output for those four records to look like exactly?
        mistyped:
        push \%data, { name => $names, address => $add, phone => $phone, email + => $email };
Re: Push values into a hash
by Maresia (Beadle) on Jul 25, 2016 at 17:19 UTC
    Could this help?
    #!/usr/bin/perl use strict; use warnings; use Data::Dump 'pp'; use Data::Dumper; use JSON; my @AoH; #Array of hash references foreach my $line (<DATA>) { chomp($line); my ($names, $add, $phone, $email) = split/,/, $line; push @AoH, { name => $names, address => $add, phone => $phone, ema +il => $email } ; } my $json = encode_json \@AoH; print Dumper $json; __DATA__ Joe, Main Street, 346 20274, test1@test.com Mary, Central Road, 02615128, test2@test.com Lou, Cannal St, 612262297692848, test3@test.com Carl, Sout St, 3268022049187, test4@test.com =result # Valid JSON [ { "email": " test1@test.com", "name": "Joe", "address": " Main Street", "phone": " 346 20274" }, { "email": " test2@test.com", "name": "Mary", "address": " Central Road", "phone": " 02615128" }, { "email": " test3@test.com", "name": "Lou", "address": " Cannal St", "phone": " 612262297692848" }, { "email": " test4@test.com", "name": "Carl", "address": " Sout St", "phone": " 3268022049187" } ] =cut
      Thank you, it worked!
Re: Push values into a hash
by haukex (Archbishop) on Jul 25, 2016 at 15:14 UTC

    Hi Anonymous,

    It would help if you could show what the input data $names and $claim looks like (with Data::Dumper or Data::Dump; you normally don't need both) and what you expect the output data to look like. At the moment, I have to guess whether you want the values of the %data hash to be array references (a "hash of arrays"), or if you want an "array of hashes" (the latter would make more sense to me). See also Short, Self Contained, Correct Example and How do I post a question effectively?

    You're using Data::Dumper to output the string after it's been encoded to JSON. To help in debugging, you could also dump %data to see what the Perl data structure you've created looks like. See also the Basic debugging checklist.

    Note that push only applies to pushing values onto arrays. To add a value to a hash after it's been created, you simply assign to the key: $hash{$key} = $value;.

    I'm guessing you might want an array of hashes. How to generate and work with them, as well as other data structures, is described in perldsc. The pages perlreftut and perlref will also be very helpful.

    Hope this helps,
    -- Hauke D