use Modern::Perl '2014'; use Number::Interval; use List::Util qw/sum/; my %raw_intervals = ( so => [ [ 10, 20 ], [ 30, 40 ] ], ge => [ [ 10, 30 ], ], ); my @interval_objects; for my $id ( keys %raw_intervals ) { for my $interval ( @{ $raw_intervals{$id} } ) { push @interval_objects, [ $id, Number::Interval->new( IncMax => 1, IncMin => 1, Min => $interval->[0], Max => $interval->[1] ) ]; } } while () { my ( $id, $value, $count ) = split; for my $interval (@interval_objects) { if ( $id eq $interval->[0] and $interval->[1]->contains($value) ) { push @$interval, $count; last; } } } for my $interval (@interval_objects) { my ( $id, $interval, @values ) = @$interval; say "$id - ", $interval->stringify, ' ', sum(@values); } __DATA__ so 10 0.05 so 11 0.03 so 25 0.15 so 35 0.3 so 36 0.25 so 37 1 ge 14 0.12 ge 20 0.4 #### ge - [10,30] 0.52 so - [10,20] 0.08 so - [30,40] 1.55