my @complete_list = (); my @sub_list = (); my $cur_id = 0; for my $rec ( @records ) { my $this_id = $rec->{ID}; # lots of other attributes here... if ( $this_id != $cur_id ) { # we crossed an ID boundary: # push a "heading" record on to the list if there # is more than one record in the sub list if ( @sub_list > 1 ) { # maybe lots of code here to build the record, # using all those attributes... push @complete_list, { # ... some record }; } # push the sub-list onto the main list and emtpy it out push @complete_list, @sub_list; @sub_list = (); } # accumulate records in the sub_list push @sub_list, { # ... some record }; # keep track of the "current" (last) ID to see when it changes $cur_id = $this_id; } #################### # here is the boundary-condition where we need to # take care of the last sub_list # cut-and-paste copy of the code inside the # ID-changed test: "if ( $this_id != $cur_id )" in the loop # YUCK! if ( @sub_list > 1 ) { # maybe lots of code here to build the record, # using all those attributes... push @complete_list, { # ... some record }; } push @complete_list, @sub_list; # all done return \@complete_list;