Note: I'm not going to bother testing these because I'm just illustrating an approach. In essence, is $l1 an ordered subset of $l2?
use List::MoreUtils qw( all first_index indexes );
# Is $l1 in $l2? It's kinda a bit destructive.
sub in_list {
my ($l1, $l2) = @_;
my $head = shift @$l1;
my $head_idx = first_index { $head eq $_ } @$l2;
return unless defined $head_idx;
# Make sure $l2 is still big enough to hold $l1
return unless $#$l2 - $head_idx >= $#$l1;
return all { $l1->[$_] eq $l2->[$_ + $head_idx] } indexes @$l1;
}
The best solution, however, will allow for an optional equality test. You never know what kind of things are in those arrays. Oh, and we shouldn't be destructive.
sub in_list {
my ($l1, $l2, $comp) = @_;
$comp ||= sub { $_[0] eq $_[1] };
my $head = $l1->[0];
my $head_idx = first_index { $comp->($head,$_) } @$l2;
return unless defined $head_idx;
# Make sure $l2 is still big enough to hold $l1
return unless $#$l2 - $head_idx >= $#$l1 - 1;
# It might be cheaper to re-compare the head elements. But, since
+$comp is potentially
# client-defined, we'd best not assume anything. $comp might not e
+ven be side-effect
# free!! *gasps*
return all { $comp->($l1->[$_ + 1], $l2->[$_ + $head_idx]) } grep
+{ $_ } indexes @$l1;
}
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?