<?xml version="1.0" encoding="windows-1252"?>
<node id="1001204" title="Re: 2D table in perl" created="2012-10-27 11:06:39" updated="2012-10-27 11:06:39">
<type id="11">
note</type>
<author id="832495">
choroba</author>
<data>
<field name="doctext">
Not as short as I hoped :-)
&lt;readmore&gt;&lt;c&gt;
#!/usr/bin/perl
use warnings;
use strict;

use Text::Table;

# Where the ranges start for C and H:
my @c_start = qw/1 3 6 11/;
my @h_start = qw/1 11 21 31/;

my @file = &lt;DATA&gt;;

my @multiply = split " ", $file[1];
shift @multiply;                       # Discard "amount:"

my $i = 0;
my %result;
for my $ch (grep @$_,                  # Ignore "num:" and whitespace
            map [/C([0-9]+)H([0-9]+)/],
            split ' ', $file[0]) {
    my ($c, $h) = @$ch;
    $result{find_range($c, @c_start)}
           {find_range($h, @h_start)}
               += $multiply[$i];
    $i++;
}

# Table header.
my $table = Text::Table-&gt;new(
            '*',
            map join('-', ranges($_, @c_start)),
            0 .. $#c_start - 1);

# Table rows.
for my $i (0 .. $#h_start-1) {
    $table-&gt;add(join ('-', ranges($i, @h_start)),
               map { $result{$_}{$i} // 0 } 0 .. @c_start);
}

print $table;


sub ranges {
    my ($idx, @arr) = @_;
    return ($arr[$idx], $arr[$idx + 1] - 1);
}

sub find_range {
    my ($value, @ranges) = @_;
    my $range_start = 0;
    $range_start++ while $ranges[$range_start + 1] &lt;= $value;
    return $range_start;
}


__DATA__
num:    C1H10 C5H30 C3H5 C2H8 
amount:   1    5     6    9   
&lt;/c&gt;&lt;/readmore&gt;

&lt;!-- Node text goes above. Div tags should contain sig only --&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-832495"&gt;

&amp;#1604;&amp;#1405;&amp;#4285;† &amp;#6514;&amp;#6482;&amp;#9898;&amp;#10186;&amp;#4281;&amp;#5651;&amp;#5511; &amp;#5045;&amp;#5651;&amp;#5511;&amp;#9137; &amp;#4281;&amp;#6514;&amp;#119243;&amp;#409;&amp;#5651;&amp;#5511;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
1001181</field>
<field name="parent_node">
1001181</field>
</data>
</node>
