http://qs1969.pair.com?node_id=593222


in reply to Re: Reconciling multiple lists (similar to "merge" in CVS?)
in thread Reconciling multiple lists (similar to "merge" in CVS?)

What do you mean by "sorted"? My example shows that one list might have elements in a different order.

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
  • Comment on Re^2: Reconciling multiple lists (similar to "merge" in CVS?)

Replies are listed 'Best First'.
Re^3: Reconciling multiple lists (similar to "merge" in CVS?)
by Util (Priest) on Jan 06, 2007 at 07:35 UTC

    Ack! I overlooked the unsorted elements in your data. By way of apology, please accept this working, tested code. It is somewhat under-documented and needs refactoring, but I am out of time tonight. For your two sample @sets, my code outputs:

    [ 0, undef, 1, undef, undef, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6, undef, 7, 8 ], [ 0, undef, 1, 2, 3, 4, 5, undef, 6, 7 ],
    and:
    [ 0, 1, 2, undef, undef, 3, 4 ], [ 0, 1, undef, 2, undef, 3, 4 ], [ 0, 1, undef, undef, 2, 3, 4 ],
    .

    The code works by transforming all the lists into AoAs, with each element holding [$original_item, $original_index]. It merges the first two lists, via Algorithm::Diff (++belg4mit) to form elements [$original_item, $index_from_list1, $index_from_list2]. List 3 is then merged in, etc. I *think* it will work fine for *any* number of lists.

      Yowza! This looks cool, and I'll check it out.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      Re: your "XXX" block, I've refactored the code thus:
      # 0 --> identical element if ( $which_list == 0 ) { die "Can't happen" if @indices1 != @indices2; foreach my $i ( 0 .. $#indices1 ) { my ( $item1, @offsets ) = @{ $list1_aref->[ $indices1[ +$i] ] }; my ( $item2, $offset ) = @{ $list2_aref->[ $indices2[ +$i] ] }; die unless $item1 eq $item2; push @offsets, $offset; push @merged, [ $item1, @offsets ]; } } # 1 --> list 1 has an element here if ( $which_list & 1 ) { foreach ( @{ $list1_aref }[ @indices1 ] ) { my ( $item1, @offsets ) = @{ $_ }; push @offsets, undef; push @merged, [ $item1, @offsets ]; } } # 2 --> list 2 has an element here if ( $which_list & 2 ) { foreach ( @{ $list2_aref }[ @indices2 ] ) { my ( $item2, $offset ) = @{ $_ }; my @offsets = map { undef() } 1 .. $offset_width; push @offsets, $offset; push @merged, [ $item2, @offsets ]; } }
      I've scrapped the 'elsifs' and used & instead of ==.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re^3: Reconciling multiple lists (similar to "merge" in CVS?)
by Joost (Canon) on Jan 06, 2007 at 00:06 UTC
      Yes, I could, but that would be solving a different problem. The out-of-orderness is something I have to take into account here.

      At least I can be sure the values themselves are unique, but they're not sortable.


      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart