in reply to Re: flattening a list-of-lists
in thread flattening a list-of-lists
Hi Limbic~Region, in response to your question in the CB I wrote the following code. It handles the issues you mention in your update as well as the fact that you are doing the wrong kind of traversal.
#!/usr/bin/perl use strict; use warnings; use Scalar::Util qw(reftype refaddr); my @array1 = ( 1 .. 10 ); my @array2 = ( qw(a b c) , [ 28, 42, 84 ] , 'foo bar' ); push @array1 , \@array2; push @array2 , \@array1; my %hash=( foo=>[qw(bar baz)], bar=>{ foo=>1, baz=>2}, baz=>\@array1, bop=>\@array2 ); print " flatten:",join(', ' , flatten(\@array1 , \@array2)),"\n"; print "lr_flatten:",join(', ' , lr_flatten(\@array1 , \@array2)),"\n"; print "* flatten:",join(', ' , flatten(\%hash)),"\n"; sub flatten { my @context; my @flat; my %seen; push @context,[0,\@_]; # index, array ref #@context could be simpler if we didnt care about #destroying the arrays that we are flattening. while (@context and $context[-1][0]<@{$context[-1][1]}) { my $item=$context[-1][1][$context[-1][0]++]; my $type=reftype $item; unless ($type) { push @flat,$item; } elsif ($type eq 'ARRAY') { push @context,[0,$item] unless $seen{refaddr $item}++; } elsif ($type eq 'HASH') { push @context,[0,[map { $_ => $item->{$_} } sort {$a cmp $b} keys %$item]] unless $seen{refaddr $item}++; } else { Carp::confess "Error! can only flatten scalars, ARRAYs and + HASHes,". " got a $type instead\n"; } pop @context unless $context[-1][0]<@{$context[-1][1]}; } return wantarray ? @flat : \@flat; }
The output I get for the two variants is below.
flatten:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a, b, c, 28, 42, 84, foo bar lr_flatten:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a, b, c, foo bar, 28, 42, 84 * flatten:bar, baz, 2, foo, 1, baz, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a, + b, c, 28, 42, 84, foo bar
The star result is from dumping a hash, something I added in just for the hell of it. :-)
Cheers,
First they ignore you, then they laugh at you, then they fight you, then you win.
-- Gandhi
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: flattening a list-of-lists (simpler)
by tye (Sage) on Nov 19, 2003 at 20:14 UTC | |
by demerphq (Chancellor) on Nov 19, 2003 at 22:39 UTC |