Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

filtering and dividing an array

by fraizerangus (Sexton)
on Nov 29, 2008 at 09:44 UTC ( [id://726754]=perlquestion: print w/replies, xml ) Need Help??

fraizerangus has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone I pretty new to PERL so you'll have to excuse me if this question sounds too stupid or easy. I basically have a big array full of magnitudes of atoms; I now have to separate into two arrays, in 2 previous arrays I have a list of the atoms I need to divide up. A beginingarray and an endingarray for example say atoms belonging to beginningarray[0]-endingarray[0] into one of the arrays and beginningarray1-endingarray1 into the other array. The array positions could contain numbers like 34-178?! Could anyone offer me any code which might help me accomplish this

Replies are listed 'Best First'.
Re: filtering and dividing an array
by Corion (Patriarch) on Nov 29, 2008 at 09:52 UTC

    I'm a bit unclear on what you want. Maybe splice already does what you want? Otherwise, likely you want to stuff the elements you want (or the ones you don't want) into a hash and part the array based on whether each element is in the hash or not. Maybe List::Part is of convenience there.

Re: filtering and dividing an array
by Dhanasekar (Acolyte) on Nov 29, 2008 at 10:31 UTC
    For joining the two arrays into a single array below is the example. The operation will be done for the number of elements in the array1, i.e., if there are 4 elements in the list then first 4 elements will be processed irrespective of the number of elements in array2.
    #/usr/bin/perl use Data::Dumper; ## Populating the Arrays with some values. @array1 = ( 1,2,3,4 ) ; @array2 = ( 'one', 'two', 'three', 'four' ); ## Initialise the index for the array $i = 0; ## Join the two array 'array1', 'array2' in a single array named 'arra +y' map { $array[$i][0] = $array1[$i] ; $array[$i][1] = $array2[$i]; $i++ + } @array1 ; print Dumper @array;
    I am not sure whether you have asked this !!

      That's not exactly what I would call "joining two arrays"; you've actually created a List of Lists. Joining arrays is much simpler than that:

      my @a = 1 .. 4; my @b = "a" .. "d"; my @c = (@a, @b); # You could even do this - no need to create a new variable: @a = (@a, @b); # Or... push @a, @b;

      There's also no need for the complex and hard-to-read map statement if you wanted to create a LoL; just as in your example, this assumes that the first array is the same length or shorter than the second one:

      my @c; push @c, [ $a[$_], $b[$_] ] for 0 .. $#a;

      Update: Added the "Or..." "push" method.


      --
      "Language shapes the way we think, and determines what we can think about."
      -- B. L. Whorf
Re: filtering and dividing an array
by Perlbotics (Archbishop) on Nov 29, 2008 at 13:26 UTC

    I understood, that you have two arrays holding the start- and end-indices respectively of several ranges ($beginingarray[i] .. $endingarray[i]) to be copied or extracted from the bigger array. So, maybe you only need copies of array-slices (see perldata)? As Corion suggested, use splice to extract ranges if you need to consume from the @bigarray.
    Maybe it's a more convenient approach to encode your ranges as list of strings (e.g. @range = qw(20-30 1-5);) or as Array-of-Array(refs) (e.g. @range = ( [20,30], [1,5] );) rather than having separate arrays of start- and end-indices?

    use strict; # ranges: 1-5, 20-30, 8-15 my @beginningarray = (1, 20, 8); my @endingarray = (5, 30, 15); #Populate: I.E. Atom#X(Magn.Y): A#0(M0), A#1(M0), ... A#30(M3) my @bigarray = map { "A\#$_(M" . int($_/8) . ")" } 0..30; # copy: leave @bigarray untouched sub copy_from_array { #start-idx, end-idx, from-array_ref my ($startidx, $endidx, $a_ref) = @_; # suggestion: add range checks return @{$a_ref}[$startidx .. $endidx]; } # extract: modify original @bigarray sub extract_from_array { #start-idx, end-idx, from-array_ref my ($startidx, $endidx, $a_ref) = @_; # suggestion: add range checks return splice @{$a_ref}, $startidx, $endidx - $startidx +1; } # example: copy and print ranges for ( my $i = 0; $i < @beginningarray; $i++ ) { my ($from, $to) = ($beginningarray[$i], $endingarray[$i]); print "copy: $from-$to:\n\t"; print join(", ", copy_from_array($from, $to, \@bigarray)), "\n"; } # When using the extraction-method, you need to reverse sort # and check for overlapping ranges! I introduced another # notation to get rid of C-ish for-loops later. # Reverse-sort intervals by start-index (no overlap-check): my @ranges = sort { $b->[0] <=> $a->[0] } ([1,5], [20,30], [8,15]); # example: extract and print ranges foreach (@ranges) { my ($from, $to) = ($_->[0],$_->[1]); print "extract: $from-$to:\n\t"; print join(", ", extract_from_array($from, $to, \@bigarray)), "\n"; } print "the rest:\n\t", join(", ", @bigarray), "\n"; # A#0(M0), A#6(M0), A#7(M0), A#16(M2), A#17(M2), A#18(M2), A#19(M2)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://726754]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-26 00:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found