Question

I am making a quick and dirty book title arrangement where titles are arranged by metatags like shelfcode, then by author, then by title. The number of metatags may vary (sorting by shelfcode, then country, then author and finally title, or something) and the number of elements may vary.

I have as a sort order

my @Stapel =  ( "133 ; 101", "smith ; jones ; harrods", "The Book of Kelts") ;

which holds 3 metatags (shelfcode, authorname, title) where the first metatag has 2 elemetns, the second one holds 3 elemetns and the last metatag holds one element.

What I want to have is output like the below where each title is arranged first by shelfcode then by each individual author then by title:

101     harrods The Book of Kelts
101     jones   The Book of Kelts
101     smith   The Book of Kelts
133     harrods The Book of Kelts
133     jones   The Book of Kelts
133     smith   The Book of Kelts

What I have so far does what i want it to do, but it is all hardcoded and too simple:

# Create an array of arrays of each element
foreach (@Stapel) {
    my @s = split / ; / ;
    print "\n - subarray has " . @s . " elements which are: '@s'" ;
    push @BIG, ( [@s] ) ;
}

for ($p=0 ; $p<@BIG ; $p++) {    
    foreach (sort @{ $BIG[$p] }   ) { 
        $a = $_ ;
        foreach (sort @{ $BIG[$p+1] }   ) {
            $b = $_ ;
            foreach (@{ $BIG[$p+2] }    ) {
                $c = $_ ;
                $Entry = "$a\t$b\t$c" ; 
                print "\n$Entry" ;
            }
        }
    }
}   # for

How do I proceed to make this more flexible, i.e. the number of elements per metatag may vary, and the number of metatags may vary as well. I tried to use recursion here but am getting quite confused.

Was it helpful?

Solution

you could use hash of arrays:

#!/usr/bin/perl
use strict;
use warnings;

my @Stapel =  ( "133 ; 101", "smith ; jones ; harrods", "The Book of Kelts") ;

sub arr_to_hash { # converts your array to an hash
  my $arr = shift;
  my %hash = ();
  $hash{shelfcode} = [ split /\s*;\s*/, $arr->[0] ];
  $hash{authorname} = [ split /\s*;\s*/, $arr->[1] ];
  $hash{title} = $arr->[2];
  return %hash;
}

my %stapel_hash = arr_to_hash(\@Stapel);

for my $shelfcode (sort @{$stapel_hash{shelfcode}}) {
  for my $author (sort @{$stapel_hash{authorname}}) {
    print "$shelfcode\t$author\t$stapel_hash{title}\n";
  }
}

I think it is almost the same complexity, but it is a little more flexible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top