Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Array manipulation

Status
Not open for further replies.

keid

Technical User
Aug 8, 2006
22
DE
I have a file containing something like that


NOD 111:119
NOD 11 12 13 14 15 16 17 18 19 20
NOD 101:109 91:100
DELNOD 21:29 2 3

111:119 means nodes 111 112 ... 119

so I have to sort the (array or hash) of NODs then romove the array of DELNOD from it

So i expect an output of an array or hash containing nodes only existing in NOD array.


Code:
@pc_data = <DAT_PC>;
close (DAT_PC);

$i = 0;
foreach $data (@pc_data)
{ 


					if ($data=~ m/\bNOD\b/)	
					{
					$nod_entity_list=substr("$pc_data[$i]", 12, 80);
					$i++;
					@arr_nod_entity_list=split(' ',$nod_entity_list);
					foreach  $data1 (@arr_nod_entity_list) {
												if ($data1=~ m/(\d+):(\d+)/)	
												{#pop @arr_nod_entity_list; 
												@range=($1.. $2);
												
												push @arr_nod_entity_list,@range;
												}
													}

					
					push @allnod,@arr_nod_entity_list;
					#print"@allnod\n";
					@sorted_nod_entity_list=sort {$a<=>$b} @allnod;
					print "@sorted_nod_entity_list\n";
					
					}
					if ($data=~ m/\sDELNOD/)	
					{$del_nod_entity_list=substr("$pc_data[$i]", 12, 80);
					$i++;
					@del_arr_nod_entity_list=split(' ',$del_nod_entity_list);
					push @del_allnod,@del_arr_nod_entity_list;
					@del_sorted_nod_entity_list=sort {$a<=>$b} @del_allnod;
					
					}
}

thanks in advance
 
I tried push pop shift unshift as these are used on the beginning or end of arrays. I added my code to give u an idea of what I did, but it is not working

any other ideas
 
I can't follow your explanation at all. You have this file, looks like this:

NOD 111:119
NOD 11 12 13 14 15 16 17 18 19 20
NOD 101:109 91:100
DELNOD 21:29 2 3

what output do you want? Show the output, as well as explain it.
 
This isn't foolproof by any means, but it might give you a place to start.
Code:
my %nodes;

while (<DATA>) {
    next unless /NOD/;
    my ($action, @nodes) = split ' ', $_;
    foreach (@nodes) {
        my @temp = ($_);
        @temp = ($1..$2) if $_ =~ /(\d+):(\d+)/;
        
        if ($action eq 'NOD') {
            map {$nodes{$_}++} @temp;
        } elsif ($action eq 'DELNOD') {
            map {$nodes{$_}--} @temp;
        } else {
            die "Bad Input!";
        }
    }
}
print "Remaining Nodes:\n";
foreach (sort {$a <=> $b} grep {$nodes{$_} > 0} keys %nodes) {
    print "$_\n";
}

print "\nDeleted Nodes:\n";
foreach (sort {$a <=> $b} grep {$nodes{$_} == 0} keys %nodes) {
    print "$_\n";
}

print "\nUnmatched Nodes:\n";
foreach (sort {$a <=> $b} grep {$nodes{$_} < 0} keys %nodes) {
    print "$_\n";
}

__DATA__
    NOD        111:119  
    NOD        11 12 13 14 15 16 17 18 19 20
    NOD        101:109  91:100
   DELNOD     21:29 2 3 19
 
Hello

first I would like to thank you guys for ur help. This is giving us much interest in the perl and its wider capabilities.

As output to this program, I just needed a sorted array containing @NODs which are not in @DELNOD.

this is the code i used to do it, it is simple up to the level of my knowledge at the moment. One good thing is that I am learning alot from ur helpful suggestions.

Code:
foreach $data (@pc_data)
{ 
					if ($data=~ m/\bNOD\b/)	
					{
					$nod_entity_list=substr("$data", 12, 80);
					@arr_nod_entity_list=split(' ',$nod_entity_list);
					foreach  $data1 (@arr_nod_entity_list) {
												if ($data1=~ m/(\d+):(\d+)/)	
												{ @range=($1.. $2);												
												push @new_array,@range;
												}
												else	{ push @new_array,$data1;}
												  }
					}
					if ($data=~ m/\sDELNOD/)	
					{$del_nod_entity_list=substr("$data", 12, 80);
					@del_arr_nod_entity_list=split(' ',$del_nod_entity_list);
					foreach  $data2 (@del_arr_nod_entity_list) {
												if ($data2=~ m/(\d+):(\d+)/)	
												{ @range2=($1.. $2);												
												push @new_array1,@range2;
												}
												else	{ push @new_array1,$data2;}
													  }
										print"@new_array1\n";
										}
}
#print"@new_array\n";	
my %seen;
@seen{@new_array}=();
delete @seen{@new_array1};
my @aonly=keys %seen;
@sorted_entity_list=sort {$a<=>$b} @aonly;
print "@sorted_entity_list";


for the subtraction i copied a code from perl cookbook, the lines my seen hash.


 
You can store the nodes in hashes rather than arrays and you don't need to worry about %seen or the extra arrays. Something similar to:
Code:
my (%nod, %delnod);

while (<DATA>) {
    next unless /NOD/;
    my ($action, @nodes) = split ' ', $_;
    foreach (@nodes) {
        my @temp = ($_);
        @temp = ($1..$2) if $_ =~ /(\d+):(\d+)/;
        
        if ($action eq 'NOD') {
            map {$nod{$_}++} @temp;
        } elsif ($action eq 'DELNOD') {
            map {$delnod{$_}++} @temp;
        } else {
            die "Bad Input!";
        }
    }
}

# Print nodes in %nod that aren't in %delnod
print "$_\n" for grep {! $delnod{$_}} sort {$a <=> $b} keys %nod;

__DATA__
    NOD        111:119  
    NOD        11 12 13 14 15 16 17 18 19 20
    NOD        101:109  91:100
   DELNOD     21:29 2 3 19
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top