splicing two arrays

M

Matija Papec

Here is the problem which IMHO isn't trivialy(in one line) solvable in
perl5; I have two arrays of same length and want to remove elements from
them depending on %h(all values are just for illustration, there is no
relation between them),

my @arr1 = 30..60;
my @arr2 = 10..40;

my %h = (
33 => 'value',
43 => 'value',
45 => 'value',
51 => 'value',
53 => 'value',
);


Now, simple grep does a right thing,
@arr1 = grep exists $h{$_}, @arr1;

but it leaves me with @arr2 where corresponding elements to @arr1 should
also be removed(when removing n-th from @arr1, remove n-th from @arr2 too).

I ended up with simultaneous array rotation and I'm curios now if there is a
better way? :)
 
U

Uri Guttman

MP> my @arr1 = 30..60;
MP> my @arr2 = 10..40;

MP> my %h = (
MP> 33 => 'value',
MP> 43 => 'value',
MP> 45 => 'value',
MP> 51 => 'value',
MP> 53 => 'value',
MP> );


MP> Now, simple grep does a right thing,
MP> @arr1 = grep exists $h{$_}, @arr1;

MP> but it leaves me with @arr2 where corresponding elements to @arr1
MP> should also be removed(when removing n-th from @arr1, remove n-th
MP> from @arr2 too).

grep on the indexes and not on the values. then slice both arrays.

my @indexes = grep $h{$arr1[$_]}, @arr1 ;

@arr1 = @arr1[@indexes] ;
@arr2 = @arr2[@indexes] ;

uri
 
D

David K. Wall

Uri Guttman said:
MP> my @arr1 = 30..60;
MP> my @arr2 = 10..40;

MP> my %h = (
MP> 33 => 'value',
MP> 43 => 'value',
MP> 45 => 'value',
MP> 51 => 'value',
MP> 53 => 'value',
MP> );
grep on the indexes and not on the values. then slice both arrays.

my @indexes = grep $h{$arr1[$_]}, @arr1 ;

You mean like this? :)

my @indexes = grep $h{$arr1[$_]}, 0..$#arr1 ;


@arr1 = @arr1[@indexes] ;
@arr2 = @arr2[@indexes] ;
 
U

Uri Guttman

MP> my @arr1 = 30..60;
MP> my @arr2 = 10..40;MP> my %h = (
MP> 33 => 'value',
MP> 43 => 'value',
MP> 45 => 'value',
MP> 51 => 'value',
MP> 53 => 'value',
MP> );
grep on the indexes and not on the values. then slice both arrays.

my @indexes = grep $h{$arr1[$_]}, @arr1 ;

DKW> You mean like this? :)

DKW> my @indexes = grep $h{$arr1[$_]}, 0..$#arr1 ;

yeah. too quick on the reply.

uri
 
M

matija

MP> Now, simple grep does a right thing,
MP> @arr1 = grep exists $h{$_}, @arr1;

MP> but it leaves me with @arr2 where corresponding elements to @arr1
MP> should also be removed(when removing n-th from @arr1, remove n-th
MP> from @arr2 too).

grep on the indexes and not on the values. then slice both arrays.

my @indexes = grep $h{$arr1[$_]}, @arr1 ;

@arr1 = @arr1[@indexes] ;
@arr2 = @arr2[@indexes] ;

Tnx, it appears that perl6 will handle this in its own way.
 
M

matija

I ended up with simultaneous array rotation and I'm curios
now if there is a better way? :)

How about:

for my $i (0..$#arr1) {
next unless exists $h{$arr1[$i]};
splice @arr1, $i, 1;
splice @arr2, $i, 1;
}

Unfortunately this doesn't work as expected as arrays continuously
shrink so when $i reaches initial $#arr1, real @arr1 is far smaller.
Or is that the "simultaneous rotation"?

Nope, something like
push @arr1, (shift @arr1);
push @arr2, (shift @arr2);
 
G

Greg Bacon

: On Thu, 31 Jul 2003 18:34:28 -0000, (e-mail address removed) (Greg Bacon)
: wrote:
:
: [...]
:
: >Oh, that's a different problem. Is there a reason you're using
: >parallel arrays rather than a list of lists?
:
: I have no real reason except I started coding in such way with two
: arrays (@arr1 has cgi-form names and @arr2 corresponding sql column
: names).

When I find myself starting to write parallel arrays, I almost always
combine them to make arrays of arrays. See the perllol manpage for the
mechanics. Doing it that way makes eliminating corresponding elements
trivial.

Greg
 
S

Steve Grazzini

matija said:
Steve Grazzini said:
I ended up with simultaneous array rotation and I'm curios
now if there is a better way? :)

How about:

for my $i (0..$#arr1) {
next unless exists $h{$arr1[$i]};
splice @arr1, $i, 1;
splice @arr2, $i, 1;
}

Unfortunately this doesn't work as expected as arrays
continuously shrink so when $i reaches initial $#arr1,
real @arr1 is far smaller.

Yeah... I read your logic backwards.

for my $i (0..$#arr1) {
next if exists $h{$arr1[$i]}; # KEEP them
splice @arr1, $i, 1;
splice @arr2, $i, 1;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top