Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re^2: Reversing the action of the while loop

by Scotmonk (Sexton)
on Nov 24, 2019 at 22:18 UTC ( [id://11109163]=note: print w/replies, xml ) Need Help??


in reply to Re: Reversing the action of the while loop
in thread Reversing the action of the while loop

The problem, I feel, is complex but perhaps you guys are more practiced in dealing with computers so it might be easier.

The difficult part of this is trying to make sense to you guys
I have lines of data elements in a .vim file (this can vary between 5 data elements per line and 25)
Each element is distinct from the others, regarded as a different sample

I have been reading one line of data and comparing it with the previous x number of lines of data, looking for matches in value
(which I have code for and can provide below)

I now have to be more specific, in that I have to read the individual data from each line, and eliminating any replication, keep adding new values until I have x amount of values.

so for example:

my input data would look something like this

1 2 6 4 5
6 7 8 9 10
1 2 11 12 13
6 14 15 16 17

If I chose to read 13 elements of data, i would read
1 2 6 4 5 6 7 8 9 10 1 2 11

Now I need to remove duplicate values, in this case one of the 1, one of the 2, and one of the 11 (but values could be triplicated or more)

so that would result in

1 2 4 5 6 7 8 9 10 11

This final line would then be compared with the next complete unread line in the file, with matches printed to one file and nonmatches printed to another as per the code below.

(so the match file would read)
6
(and the nonmatch file would read)
14 15 16 17

Now there is actually another step to what I do on paper that I would like the PERL script to perform

Initially I had chosen 13 values (and this can vary between 5 and upto 80)

If it is the case that duplicates are removed, I dont have the 13 values that I originally planned for

so on paper, I continue to read forward until I have my required number of values filled in (without duplicates)

even if that means reading into more lines of data, and moving forward the line that I will eventually compare with

Does this make any sense at all ? :)

thankyou
my $line = 4; while (@lines > 3) { # check first 3 lines against the 4th line my @vals = split /\s+/, $lines[3]; my @chk = split /\s+/, join(' ', @lines[0..2]); my %match; foreach my $val (@vals) { $match{$val}++ if grep { $val eq $_ } @chk; } my @match = sort keys %match; my @nomatch = grep { not exists $match{$_} } @vals; my $match = @match; my $nomatch = @nomatch; # do whatever you want with the matches and no-matches print MATCH "$line: \tmatch = @match\n"; print NOMATCH "$line: \tnomatch = @nomatch\n"; $line++; # get rid of first line so next loop will be 2-6 and so on shift @lines; }

Replies are listed 'Best First'.
Re^3: Reversing the action of the while loop
by tybalt89 (Monsignor) on Nov 24, 2019 at 23:53 UTC

    Here's my guess at something like what you want. Instead of printing @match and @nomatch at the end, just write their contents to the proper files, and change the input to read from your input file.

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11109150 use warnings; my $x = 9; my %uniques; my @match; my @nomatch; while( <DATA> ) { print; for my $element ( split ) { if( keys %uniques < $x ) { $uniques{ $element }++; } else { if( $uniques{ $element } ) { push @match, $element; } else { push @nomatch, $element; } } } } print "\nMATCH:\n@match\n\nNOMATCH:\n@nomatch\n"; __DATA__ 1 2 6 4 5 6 7 8 9 10 1 2 11 12 13 6 14 15 16 17

    Outputs:

    1 2 6 4 5 6 7 8 9 10 1 2 11 12 13 6 14 15 16 17 MATCH: 1 2 6 NOMATCH: 11 12 13 14 15 16 17
Re^3: Reversing the action of the while loop
by marioroy (Prior) on Nov 25, 2019 at 07:03 UTC

    Hi Scotmonk,

    This is a great use-case for using an ordered hash (like a hash but with key insertion order preserved). Fortunately, such a module exists. For this demonstration, I'm more interested in the hash keys, not the hash values (i.e. hash key-driven implementation).

    # https://www.perlmonks.org/?node_id=11109163 use strict; use warnings; use feature 'say'; use Hash::Ordered; tie my %elems, 'Hash::Ordered'; tie my %match, 'Hash::Ordered'; tie my %nomatch, 'Hash::Ordered'; my $skip_duplicates = 0; # set to 1 to skip duplicates my $num_elements = 13; # number of elements to read my $num_read = 0; # number of elements read my @lines = <DATA>; chomp @lines; # read elements while ( @lines && $num_read < $num_elements ) { my $line = shift @lines; foreach my $elem ( split / /, $line ) { if ( $skip_duplicates ) { $num_read++ unless exists $elems{ $elem }; } else { $num_read++; } $elems{ $elem } = undef; last if $num_read == $num_elements; } } say "data elements"; say join(' ', keys %elems); # matched, not matched if ( @lines ) { foreach my $elem ( split / /, shift @lines ) { ( exists $elems{ $elem } ) ? $match{ $elem } = undef : $nomatch{ $elem } = undef; } say "match"; say join(' ', keys %match); say "nomatch"; say join(' ', keys %nomatch); } else { say "no more lines"; } __DATA__ 1 2 6 4 5 6 7 8 9 10 1 2 11 12 13 6 14 15 16 17 2 18 19 20 21

    Output: $skip_duplicates = 0

    data elements 1 2 6 4 5 7 8 9 10 11 match 6 nomatch 14 15 16 17

    Output: $skip_duplicates = 1

    data elements 1 2 6 4 5 7 8 9 10 11 12 13 14 match 2 nomatch 18 19 20 21

    Regards, Mario

      Thankyou Mario

      I get an error on execution
      Can't locate Hash/Ordered.pm in @INC (@INC contains: C:/Dwimperl/perl/site/lib C:/Dwimperl/perl/vendor/lib C:/Dwimperl/perl/lib .) at compare001.pl line 7.

      How can I remedy this ?
      Thankyou
      Michael

        You have to install the library: cpanm Hash::Ordered.

      I successfully installed Hash::Ordered
      still gettng this message. Is there something else I should do ?
      Can't locate Hash/Ordered.pm in @INC (@INC contains: C:/Dwimperl/perl/site/lib C:/Dwimperl/perl/vendor/lib C:/Dwimperl/perl/lib .) at compare001.pl line 8. BEGIN failed--compilation aborted at compare001.pl line 8.
        I successfully installed Hash::Ordered ... still gettng this message. Is there something else I should do ? ... Can't locate Hash/Ordered.pm

        Do you perhaps have two installations of Perl on your machine, and you installed it into the wrong one?

        Have you tried cpanm from the bin directory (assuming cpanm lives there). Not having Dwimperl, I took a guess for where the bin directory might be.

        C:\Dwimperl\perl\bin\cpanm Hash::Ordered

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2024-04-18 10:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found