Re: Data::Rmap to modify an arrayref of arrayrefs
by GrandFather (Saint) on Jul 02, 2011 at 02:21 UTC
|
use strict;
use warnings;
use Data::Dump qw();
use Data::Rmap qw();
my $initial = [note => [shopping => ['item']]];
Data::Rmap::rmap_array {
return $_ if $_->[0] ne 'shopping'; # Ignore non-shopping entries
my @item= map {[item => $_]} qw(bread butter beans);
$_->[1] = ['shopping', @item];
Data::Rmap::cut ($_);
} $initial;
print Data::Dump::dump ($initial), "\n";
Prints:
[
"note",
[
"shopping",
[
"shopping",
["item", "bread"],
["item", "butter"],
["item", "beans"],
],
],
]
True laziness is hard work
| [reply] [d/l] [select] |
|
|
That is not the target structure specified in the OP:
[
'note',
[
'shopping',
[ item => 'bread' ],
[ item => 'butter' ],
[ item => 'beans' ],
]
];
| [reply] [d/l] |
|
|
use strict;
use warnings;
use Data::Dump qw();
use Data::Rmap qw();
my $initial = [note => [shopping => ['item']]];
Data::Rmap::rmap_array {
return $_ if $_->[0] ne 'shopping'; # Ignore non-shopping entries
my @item= map {[item => $_]} qw(bread butter beans);
$_ = ['shopping', @item];
Data::Rmap::cut ($_);
} $initial;
print Data::Dump::dump ($initial), "\n";
prints:
[
"note",
[
"shopping",
["item", "bread"],
["item", "butter"],
["item", "beans"],
],
]
True laziness is hard work
| [reply] [d/l] [select] |
Re: Data::Rmap to modify an arrayref of arrayrefs
by Khen1950fx (Canon) on Jul 02, 2011 at 00:00 UTC
|
It wouldn't do 'item' => 'bread' but it would do
bread =>. This was as close as I could get:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Rmap qw(:all);
my @item = ('bread', 'butter', 'beans');
my $initial =
[
note =>
[
shopping =>
[
$item[0] =>
$item[1] =>
$item[2] =>
],
],
];
use Data::Dumper;
my ($dump) = rmap_array {
if ($_->[0] eq 'shopping') {
my @item;
for my $item qw(bread butter beans) {
push @item, [ item => $item ];
}
my $newdata = [ shopping => \@item ];
cut($newdata)
} else {
$_;
}
} my @item ;
warn Dumper($initial, $dump);
Updated: fixed typo | [reply] [d/l] [select] |
|
|
It wouldn't do 'item' => 'bread' but it would do bread =>. This was as close as I could get
This data is for consumption by new_from_lol in HTML::Element.
| [reply] [d/l] |
Re: Data::Rmap to modify an arrayref of arrayrefs
by kcott (Archbishop) on Jul 02, 2011 at 02:14 UTC
|
I haven't used Data::Rmap before so others may have better answers. However, the following works and solves your problem.
use strict;
use warnings;
use Data::Rmap qw(:all);
my $initial = [ note => [ shopping => [ 'item' ] ] ];
use Data::Dumper;
# build a list of shopping items ** for reuse **
my @shopping_items;
for my $item qw(bread butter beans) {
push @shopping_items, [ item => $item ];
}
my ($dump) = rmap_array {
# If we get an arrayref whose first element is 'shopping'
if ($_->[0] eq 'shopping') {
# Make the second element the shopping list
$_->[1] = [ @shopping_items ];
# No need to drill down any further
cut($_);
} else {
# if the arrayrefs first element is not 'shopping'
# then simply pass it through
$_;
}
} $initial;
warn Dumper($initial, $dump);
| [reply] [d/l] |
|
|
Thanks kcott. I've gone ahead and abstracted htis into a function. Now, I'm going to try to solve it at the level of 'items' instead of at the parent level.
use strict;
use warnings;
use Data::Rmap qw(:all);
use Data::Dumper;
my $initial_lol = [ note => [ shopping => [ item => 'sample' ] ] ];
# In $initial_lol, the new child of shopping is shopping_items
my $new_lol = newchild($initial_lol, shopping => shopping_items());
warn Dumper($new_lol);
sub newchild {
my ($lol, $parent_arrayref_label, $new_child)=@_;
my ($mapresult) = rmap_array {
if ($_->[0] eq $parent_arrayref_label) {
$_->[1] = $new_child;
cut($_);
} else {
$_;
}
} $lol;
$mapresult;
}
sub shopping_items {
my @shopping_items;
for my $item qw(bread butter beans) {
push @shopping_items, [ item => $item ];
}
\@shopping_items;
}
| [reply] [d/l] |
|
|
tada! now I work at the item level instead of it's parent:
use strict;
use warnings;
use Data::Rmap qw(:all);
use Data::Dumper;
my $initial_lol = [ note => [ shopping => [ item => 'sample' ] ] ];
# In $initial_lol, the new child of shopping is shopping_items
my $new_lol = newnode($initial_lol, item => shopping_items());
warn Dumper($new_lol);
sub newnode {
my ($lol, $node_label, $new_node)=@_;
my ($mapresult) = rmap_array {
if ($_->[0] eq $node_label) {
$_ = shopping_items();
cut($_);
} else {
$_;
}
} $lol;
$mapresult;
}
sub shopping_items {
my @shopping_items;
for my $item qw(bread butter beans) {
push @shopping_items, [ item => $item ];
}
\@shopping_items;
}
| [reply] [d/l] |
|
|
Re: Data::Rmap to modify an arrayref of arrayrefs
by metaperl (Curate) on Jul 02, 2011 at 10:43 UTC
|
I had to do some ugly in-place modification:
use strict;
use warnings;
use Data::Rmap qw(:all);
my $initial =
[
note =>
[
shopping =>
[ 'item' ]
]
];
use Storable qw(dclone);
my $clone = dclone $initial;
use Data::Dumper;
my ($dump) = rmap_all {
if (ref and $_->[0] eq 'shopping') {
my @item = map { [ item => $_ ] } qw(bread butter beans);
warn Dumper(\@item);
my $newdata = [ shopping => \@item ];
$_ = $newdata;
} else {
$_ = $_;
}
} $clone ;
warn Dumper($initial, $dump);
| [reply] [d/l] |
|
|
} else {
$_ = $_;
which does nothing, and why:
my $newdata = [ shopping => \@item ];
$_ = $newdata;
when you could just:
$_ = [ shopping => \@item ];
or maybe even:
$_ = [shopping => [map {[item => $_]} qw(bread butter beans)]];
for the whole if block.
True laziness is hard work
| [reply] [d/l] [select] |
Re: Data::Rmap to modify an arrayref of arrayrefs
by Khen1950fx (Canon) on Jul 02, 2011 at 22:57 UTC
|
}
else {
$_ = $_;
}
It didn't work. I tried return in its place, but that also doesn't work, so I just used $_;.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Rmap qw(:all);
use Data::Dump qw(dump);
use Storable qw(dclone);
my $initial = ['note', ['shopping', ['item']]];
my $clone = dclone $initial;
my($dump) = rmap_all {
if( ref and $_->[0] eq 'shopping' ) {
my @item = map { [ 'item' => '=>' => $_ ] } qw(bread butter beans)
+;
my $newdata = [ shopping => \@item ];
$_ = $newdata;
}
else {
$_
}
}
$clone;
print dump($dump);
| [reply] [d/l] [select] |