LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-29-2006, 08:49 AM   #1
Grafbak
Member
 
Registered: Jun 2003
Location: /dev/null
Distribution: Knoppix 3.3
Posts: 61

Rep: Reputation: 15
nested loop in Perl help needed


Dear all,


I am having some trouble getting a nested loop to work properly in Perl (ActiveState 5.7.8)

I have two files filled with numbers. File1 and File2.
I need to check if every value from File1 occurs in File2.
The best method seemed to take a line from File1, make an array, split it and get the number.
Once i have this number i want to start a loop, to go through File2, to look for an occurence of this number.
As i'm typing this i'm thinking there must be more than one way to do it, but i wouldn't know how.

Here's my code :

Code:
while ($record_NEW = <NEW>)
        {
        chomp;
        @lines_NEW                  = split(/;/,$record_NEW);
        $ItemId_NEW                 = @lines_NEW[1];
        $Quantity_NEW               = @lines_NEW[2];
        $ItemName_NEW               = @lines_NEW[3];
        $price_EU_06_NEW            = @lines_NEW[4];
        $price_EU_07_NEW            = @lines_NEW[5];
        $price_UK_06_NEW            = @lines_NEW[6];
        $price_UK_07_NEW            = @lines_NEW[7];
         print "$ItemId_NEW\n";

             foreach ($record_ITM = <ITM>)
             {
             @lines_ITM            = split(/,/,$record_ITM);
             $ItemId_ITM           = @lines_ITM[5];
             print TRS "$ItemId_NEW\n";
             print TRS "$ItemId_ITM\n";
             }
           }
The most logical answer would be to place some extra {} around the second loop, but unfortunately this gives the same result.
I also have tried different loops (while and for) but i can't get it to work.

I am getting this as a result:

File1 File2
1 1
2 2
3 3
4 4

Buit what i want is this :

File1 File2
1 1
1 2
1 3
1 4

and the next :

File1 file2
2 1
2 2
2 3
2 4


If someone can please help me i'd be very thankfull. I have been at it all day and i am really out of options here.

Thank you in advance.

Last edited by Grafbak; 11-29-2006 at 08:50 AM.
 
Old 11-29-2006, 09:00 AM   #2
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
I'd probably use a hash instead of an array, and then just check if a value is defined.
 
Old 11-29-2006, 09:08 AM   #3
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Like this:
Code:
#!/usr/bin/perl -w

my %one_lines;
my %two_lines;

open(FILE, "<one") || die "can't open file one : $!\n";
while (<FILE>) {
    chomp;
    $one_lines{$_} = 1;
}
close(FILE);

open(FILE, "<two") || die "can't open file two : $!\n";
while (<FILE>) {
    chomp;
    $two_lines{$_} = 1;
}
close FILE;

foreach my $value (keys %one_lines) {
    if ( ! defined( $two_lines{$value} ) ) {
        print "$value exists in file one but not file two\n";
    }
    else {
        print "$value exists in file one AND file two\n";
    }
}
The dis-advantage is that you lose the ordering of the lines from file one - the keys %hash function doesn't return the keys in the same order they were added.
 
Old 11-29-2006, 09:29 AM   #4
Grafbak
Member
 
Registered: Jun 2003
Location: /dev/null
Distribution: Knoppix 3.3
Posts: 61

Original Poster
Rep: Reputation: 15
Thank you for your (very fast) response.
I see that i have much to learn about hashes.
The goal is to see what numbers from file1 occur in file2. The numbers that do not occur in file2 should be written to a 'trashfile' that i can send back to the person who delivered the data to me.
I'll have to dive into it in order to understand your answer.
As soon as i discover what actually is happening and tested it, i'll let you know if it worked.

The reason i used the arrays, is that it enabled me to read the files line by line.
File 2 contains 17000 lines, and i didn't know if i could fit it all into 1 variable/hash/map/array/string.

Nonetheless thank you, i'll have a go at it and let you know.

Last edited by Grafbak; 11-29-2006 at 09:31 AM.
 
Old 11-29-2006, 09:48 AM   #5
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
You could still use a hash if you wanted to read only one file into memory. The advantage of using a hash for this is that if you have repeated numbers in the set, you only use one element of a hash.

For example if the file contains
Code:
1
1
1
2
2
4
4
4
4
4
...then the hash will only contain three keys: 1, 2, and 4, whereas an array would contain ten items.

Here's a re-written script which only holds one of the file's sets in memory at once (file "two")
Code:
#!/usr/bin/perl -w

use strict;

my %two_lines;

open(FILE, "<two") || die "can't open two : $!\n";
while(<FILE>) {
    chomp;
    $two_lines{$_} = 1;
}
close(FILE);

open(FILE, "<one") || die "can't open one : $!\n";
while(<FILE>) {
    chomp;
    if ( defined($two_lines{$_}) ) {
        print "value $_ from one exists in file two\n";
    }
    else {
        print "value $_ from one DOES NOT exist in file two\n";
    }
}
close(FILE);
 
Old 12-17-2006, 08:10 AM   #6
mcummings
LQ Newbie
 
Registered: Oct 2006
Location: Fredericksburg, Va, USA
Distribution: Gentoo
Posts: 9

Rep: Reputation: 0
I'd toss some scope into this as well - a few my's to keep things from carrying over to the next iteration. otherwise all of this risks running in global scope, at which point you've got the chance of an element not getting updated the way you expect it to.
 
Old 12-18-2006, 02:24 PM   #7
Grafbak
Member
 
Registered: Jun 2003
Location: /dev/null
Distribution: Knoppix 3.3
Posts: 61

Original Poster
Rep: Reputation: 15
Thank you for the advise.

At the moment the script is doing what it's supposed to do.
According to most programming tut's using the 'my' would indeed be a sensible thing to do. I don't know if it's really usefull with tiny scripts like my own, but it can prevent nasty errors.

Especially the hash-function i learned turned out to be very usefull.

Thank you all again for the help.
 
Old 12-18-2006, 06:51 PM   #8
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Personally I recommend using:

#!/usr/bin/perl -w
use strict; # Enforce declarations

in all progs, even temp test ones. Prevents you from thinking something works when in fact it relies on globals and side effects.
Incidentally, you may see
use warnings;
after use strict; instead of the '-w' flag.
 
Old 12-18-2006, 10:01 PM   #9
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
I second chrism01's advise about warnings and strict. Saved me a lot of pain over the years.
 
Old 12-19-2006, 10:28 AM   #10
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 735

Rep: Reputation: 76
Hi, Grafbak.

For your future consideration:
Quote:
Perl Best Practices offers a collection of 256 guidelines on the art of coding to help you write better Perl code--in fact, the best Perl code you possibly can. The guidelines cover code layout, naming conventions, choice of data and control structures, program decomposition, interface design and implementation, modularity, object orientation, error handling, testing, and debugging.

http://www.oreilly.com/catalog/perlbp/
Of the Ten Essential Code Practices,
Code:
use strict;
use warnings;
are at the very top.

One can easily make a template that contains the skeleton of a perl script with all the boilerplate that a person desires already coded in ... cheers, makyo
 
  


Reply

Tags
loop, perl



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
perl loop jazman Programming 3 07-05-2006 10:31 AM
Nested-double loop error Harry Seldon Programming 3 05-06-2006 05:15 PM
loop through string with perl lfur Programming 2 07-03-2004 08:05 AM
Need help with perl loop! morbid_ru Programming 1 02-24-2004 01:14 PM
Need help with perl loop! morbid_ru Programming 2 02-17-2004 05:15 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:10 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration