Preserving Array Values Positions

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • virtualweb
    New Member
    • Aug 2007
    • 30

    Preserving Array Values Positions

    Hello:

    I have two lists of emails saved in flat files one email per line.

    My script removes the emails in list 2 if they are present in list 1. Then reprints the email list, one email per line, back into list 2 but without the weeded out emails.

    Except that when reprinting back to list 2 the order is random and I want to preserve the same order in which the emails were at first.

    EXAMPLE:
    if in email list 1 I have:

    email_02@server .com
    email_04@server .com
    email_06@server .com
    email_08@server .com
    email_10@server .com

    and if in email list 2 I have:

    email_01@server .com
    email_02@server .com
    email_03@server .com
    email_04@server .com
    email_05@server .com
    email_06@server .com
    email_07@server .com
    email_08@server .com
    email_09@server .com
    email_10@server .com

    I want to end up with:

    email_01@server .com
    email_03@server .com
    email_05@server .com
    email_07@server .com
    email_09@server .com

    But Im getting :

    email_09@server .com
    email_03@server .com
    email_07@server .com
    email_05@server .com
    email_01@server .com

    Here is my script:

    Code:
    foreach (@All_Emails_1) {
    chomp;
       
       if( /\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6}/ ){
       	$valid_emails{$_} = '1';
       	
       }
       }
    foreach(@All_Emails_2){
    	chomp;
    	if( $valid_emails{$_} eq '1' ){
    print"<B>($valid_emails{$_}) ($_)<br>";		
    		delete($valid_emails{$_});
    		push @repeated_emails,$_;
    	}
    }
    my @New_All_Emails_1 = keys(%valid_emails);
    
    
    $Back_Up_Emails_1 = 'All_Emails_BKUP.txt';
    $Old_All_Emails_1 = 'All_Emails_1.txt';
    $New_All_Emails_1 = 'All_Emails_1.txt';
    
    rename($Old_All_Emails_1, $Back_Up_Emails_1)|| die print"Cant rename $Back_Up_Emails_1";
    
    open (EMAILLIST, ">>$New_All_Emails_1") || die print"<br><b>Error: Cant open $New_All_Emails_1";
    flock (EMAILLIST);
    foreach $email @New_All_Emails_1){
    print EMAILLIST "$email\n";
    }
    flock (EMAILLIST, 8);
    close (EMAILLIST);
    Thanx for your help
    virtualweb
  • numberwhun
    Recognized Expert Moderator Specialist
    • May 2007
    • 3467

    #2
    I guess my suggestion would be to do a sort:

    Code:
    foreach $email (sort(@New_All_Emails_1)){
        print EMAILLIST "$email\n";
    }
    I haven't tested it, but that should do what you want. Let us know if it works.

    Regards,

    Jeff
    Last edited by eWish; Nov 12 '09, 03:22 AM. Reason: Fixed Code Tag

    Comment

    • virtualweb
      New Member
      • Aug 2007
      • 30

      #3
      Hello numberwhun :

      Thanx for your quick response.

      I thought sort was used to arrange a list in a particular order. Alphabetically or from smaller to higher.

      For ease of explanation I used the numerical emails 1 through 10, But emails surelly be very different in real life, and if I have emails in the follwing list:

      zebra@server.co m
      young@server.co m
      xylophone@serve r.com
      anthony@server. com

      and suppose young@server.co m gets weeded out, sort would arrange my list like this:

      anthony@server. com
      xylophone@serve r.com
      zebra@server.co m

      and what I need is this: (what you might call a first comes first serve situation)

      zebra@server.co m
      xylophone@serve r.com
      anthony@server. com

      My guess is that I need to assign a number to each email prior to weeding out the repeated emails and then as you say sort the numbers and just print back the emails in an ascendent order .. but I am not good working with hashes yet.
      Last edited by virtualweb; Nov 12 '09, 03:48 PM. Reason: typos

      Comment

      • mohanprasadgutta
        New Member
        • Dec 2007
        • 33

        #4
        re: Preserving Array Values Positions

        Hi,

        Please try this code.

        Code:
        use strict;
        my (@list1, @list2, @new_list2);
        # read from flat files
        # assume @list1 is from list1.txt
        open (LIST1, "list1.txt");
        @list1 = <LIST1>;
        close(LIST1);
        
        # assume @list2 is from list2.txt
        open (LIST2, "list2.xt");
        @list2 = <LIST2>;
        close(LIST2);
        
        foreach my $email (@list2) {
           my @exists = grep { $_ eq $email } @list1;
           push @new_list2, $email unless @exists > 0;
        }
        
        # write @new_list2 to list2.txt
        open(NEW_LIST2, ">list2.txt");
        foreach (@new_list2) {print NEW_LIST2 $_."\n";}
        close(NEW_LIST2);
        Regards,
        Mohan

        Comment

        • RonB
          Recognized Expert Contributor
          • Jun 2009
          • 589

          #5
          Code:
          #!/usr/bin/perl
          
          use strict;
          use warnings;
          use Data::Dumper;
          
          my %list1;
          
          open my $ilst1, '<', 'list1.txt' or die $!;
          while (<$list1>) {
              chomp;
              $list1{$_}++;
          }
          close $list1;
          
          my @filtered;
          open my $list2, '<', 'list2.txt' or die $!;
          while (<$list2>) {
              chomp;
              push(@filtered, $_) unless exists $list1{$_};
          }
          close $list2;
          
          print Dumper \@filtered;

          Comment

          • numberwhun
            Recognized Expert Moderator Specialist
            • May 2007
            • 3467

            #6
            For your issue with hashes, try this reference.

            Regards,

            Jeff

            Comment

            Working...