tags:

views:

258

answers:

6
 %a = ( "KEY" => {  
                    "p1" => 1 , [1223],
                    "p1" => 2 , [2323],
                    "p1" => 3 , [2353],
                 }
       );

I want to generate a structure like this. I have tried with this code:

@array = ( 1223 , 2323 ,2353 );
$count = 0; 
foreach my $i (@array) {
    $a{"KEY"} => {  "p1" => $count , [$i] };
    $count++;
}

How can I create such a hash?

+3  A: 

You're trying to store multiple values per key in the same hash. That doesn't work. Your example code also has several syntax errors, like missing semicolons, using => instead of = for assignment.

Assuming we modify your data structure to look like this:

%a = ( "KEY" => {  
                "p1" => [1 , 1223],
                "p2" => [2 , 2323],
                "p3" => [3 , 2353],
});

You can build this structure like this:

use strict;
use warnings;

my %a = ();
my @array = (1223, 2323, 2353);
my $count = 0; 
foreach my $i (@array) {
    $a{"KEY"}{"p$count"} = [$count, $i];
    $count++;
}
Lars Haugseth
+2  A: 

You can't create a structure like that.

First, 1, [1223] is not a scalar.

You could have [1, 1223]

Second, you can't use the same key name multiple times. So reusing p1 is impossible.

David Dorward
+6  A: 

The above data structure cannot be realised as hashes can have unique keys only. You should replace the value of the key KEY to an ARRAYREF instead of a HASHREF.

The following program seems to do what you want by using ARRAYREFs.

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @array = ( 1223, 2323, 2353 );
my ( $count, %hash ) = (0);

for (@array) {
    push @{ $hash{KEY}->{SUBKEY} }, { p1 => $count, v2 => $array[$count] };
    $count++;
}

print Dumper \%hash;
Alan Haggai Alavi
I agree that this the answer . But i just want to understand my strtucture is wrong for acheive the my xml
joe
@Krish: Sorry, I did not understand what you meant. Can you please elaborate a bit?
Alan Haggai Alavi
Acutally i am looking for this data strtucture %a = ( "KEY" => { "SUBKEY" => [ { "p1" => 1, "v2" => 1223, } { "p1" => 2, "v2" => 2323, } { "p1" => 3 , "v2" => 2353, }] } );
joe
What is modification i need in push ?
joe
I have updated the code. However, please try to read the perldocs pointed to by other members so that you will have a better understanding of the data structures in Perl.
Alan Haggai Alavi
+2  A: 
use Data::Dumper::Simple;

@array = ( 1223 , 2323 ,2353 );
my %a = ();
my %b = ();

for (my $i = 0; $i < scalar @array; $i++) {
    $b{"p$i"} = [$i+1, $array[$i]];
}
$a{"KEY"} = \%b;

print Dumper(%a);
Bart J
+1  A: 

Fastest, easiest--and most maintainable way--I know to write that is:

use English qw<$RS>;
#use Smart::Comments;
use YAML;

my $s = do { local $RS; Load( <DATA> ); };
### $s
# Above "smart comment" does roughly the same thing as: 
use Data::Dumper;
print Dumper( $s );

__DATA__
---
KEY:
  p1:
    -
      - 1
      - 1223
    -
      - 2
      - 2323
    -
      - 3
      - 2353

But really, XML is more of a list of lists (with some header information) type of construct. The tags work well as name-value lists. I'd recommend more of this type of structure:

---
- name  : KEY
  p1   : 1
  text : 1223
- name : KEY
  p1   : 2
  text : 2323
- name : KEY
  p1   : 3
  text : 2353

Or even the more spec-sound:

---
- node-name  : KEY
  attributes :
    -
      - p1
      - 1
  children : 
    - 1223

Which preserves order

Axeman
A: 
use Data::Dumper;
my @array = ( 1223 , 2323 ,2353 );
my $count = 1;
my @result;

# build it
push(@result, {"p1" => [$count, $_]}), $count++ foreach @array;
# show it
print Dumper(\@result);

sub xml {
    my ($key, $index, $value) = @_;
    print "<KEY ", qq($key="$index">), $value, "</KEY>";
}

# unravel it, producing results
map {
    my %hash = %$_;
    my @key = keys(%hash);
    my $key = shift(@key);
    my @value = @{$hash{$key}};
    xml($key, @value);
} @result;

# but, since your xml attribute doesn't change, nor does the
# tag, you're unnecessarily obfuscating the problem, so
# this will do (ignore the above code):

my @array = ( 1223 , 2323 ,2353 );
my $count = 1;
map {
    print qq(<KEY p1="$count">$_</KEY>);
    $count++;
} @array;
print "\n";

With Perl, data structures can be as complex as you want, but this is a case of KISS.

xcramps