Perl, creating new data (new hash) using two different hash tables

I ran into a very difficult problem (in my perspective as a beginner), and I'm not sure how to solve it. I can think of a workflow, but not a script.

I have a file A that looks like this: Teacher (tab) Student1 (space) Student2 (space) ..

Fiona       Nicole Sherry 
James       Alan Nicole
Michelle    Crystal 
Racheal     Bobby Dan Nicole

They sometimes have numbers next to their names when there are two identical names (for example, John1, John2). Students may also overlap if they have more than two advisers.

File B is a file that contains groups of teachers. It is similar, but the values ​​are separated by a comma.

Fiona       Racheal,Jack
Michelle    Racheal
Racheal     Fiona,Michelle
Jack        Fiona

The trend in file B is that the key has multiple values, and each value becomes the key, and it’s easy to find who is grouped with whom.

, , , , , , /​​. , script :

  • A
  • B, , , ( , ). , , , -, , Fiona. ( , ), -.

    while (<Group>) {
        chomp;
        $data=$_;
        $data=~/^(\S+)\s+(.*)$/;
        $TeacherA=$1;
        $group=$2; 
    
  • , (Racheal, Jack). 1 (Racheal)

    if (defined??) {
        while ($list=~/(\w+)(.*)/) {
            $TeacherB=$1;
            $group=$2;
    
  • A Racheal.
  • ( -) , 2.
  • .

    Nicole  Bobby,Dan,Nicole    Fiona   Racheal
    Sherry  Bobby,Dan,Nicole    Fiona   Racheal
    

    , . , , , :

    Nicole  Bobby,Dan,Nicole    Fiona   Racheal
    Sherry  Bobby,Dan,Nicole    Fiona   Racheal
    Nicole  David               Fiona   Jack
    Sherry  David               Fiona   Jack
    

. , , - , . . - .

+3
2

, , , . , , . , . , - , .

, . , A B .

my $file_a = qq~Fiona\tNicole Sherry
James\tAlan Nicole
Michelle\tCrystal
Racheal\tBobby Dan Nicole
~;

my $file_b = qq~Fiona\tRacheal,Jack
Michelle\tRacheal
Racheal\tFiona,Michelle
Jack\tFiona
~;

"".

# 1: Store file A in a hash
my (%file_a);
foreach my $a (split /\n/, $file_a) {
  my @temp = split /\t/, $a;
  $file_a{$temp[0]} = $temp[1];
}

# 2: Go through file B
foreach my $b (split /\n/, $file_b) {
  my @line_b = split /\t/, $b;
  # Look in stored file A if the teacher is there
  if (exists $file_a{$line_b[0]}) {
    my (%new_hash_table, @teachers);
    # Put all the students of this teacher into a new hash
    $new_hash_table{$_} = '' foreach split / /, $file_a{$line_b[0]};

    # 3: Take one of the group of teachers who are grouped with the 
    # current teacher at a time
    foreach my $teacher (split /,/, $line_b[1]) {
      if (exists $file_a{$teacher}) {
        # 4: This teacher from the group has students listen in file A
        push @teachers, $teacher; # Store the teacher name for print later
        foreach (keys %new_hash_table) {
          # 5: Fill the students as csv for the student keys from step 2
          $new_hash_table{$_} = join(',', split(/ /, $file_a{$teacher}));
        }
      }
    }
    foreach my $student (keys %new_hash_table) {
      # 6: Print...        
      print join("\t", 
        # Student-student relation
        $student, $new_hash_table{$student}, 
        # Teacher-teacher relation
        $line_b[0], @teachers);
      print "\n";
    }
  }
}

:

Sherry  Bobby,Dan,Nicole    Fiona   Racheal
Nicole  Bobby,Dan,Nicole    Fiona   Racheal
Crystal Bobby,Dan,Nicole    Michelle    Racheal
Bobby   Crystal Racheal Fiona   Michelle
Nicole  Crystal Racheal Fiona   Michelle
Dan Crystal Racheal Fiona   Michelle

, , , .

, , .

, $data=~/^(\S+)\s+(.*)$/;, . -.

<FILEHANDLE>, , , while, :

while (my $data = <GROUP>) {
      chomp $data

, , .

"Learning Perl". , , . , .

+1

, , A, , ... perl. .

$data = {};
# pull in students
open(IN, "students.txt");
while(my $line = <IN>) {
  chomp($line);
  my ($teacher, @students) = split(/\s+/,$line);
  $data->{$teacher}->{students} = \@students;
}
close IN;
# pull in teachers
open(IN, "teachers.txt");
while(my $line = <IN>) {
  chomp($line);
  my ($teacher, $supporters) = split(/\s+/,$line);
  my @supporters = split(/,/,$supporters);
  $data->{$teacher}->{supporters} = \@supporters;
}
close IN;
# make the output
foreach my $teacher (keys %{$data}){
  foreach my $teacher_student (@{$data->{$teacher}->{students}}) {
    foreach my $supporter (@{$data->{$teacher}->{supporters}}){
      my $num_supporter_students = @{$data->{$supporter}->{students}} + 0;
      if($num_supporter_students) {

        print "$teacher_student\t" . 
              join(",",@{$data->{$supporter}->{students}}) .
              "\t$teacher\t$supporter\n";
      }
    }
  }
}

, , :

Crystal Bobby,Dan,Nicole    Michelle    Racheal
Nicole  Bobby,Dan,Nicole    Fiona   Racheal
Sherry  Bobby,Dan,Nicole    Fiona   Racheal
Bobby   Nicole,Sherry   Racheal Fiona
Bobby   Crystal Racheal Michelle
Dan Nicole,Sherry   Racheal Fiona
Dan Crystal Racheal Michelle
Nicole  Nicole,Sherry   Racheal Fiona
Nicole  Crystal Racheal Michelle
+1

All Articles