【问题标题】:How do i push a value from a hash onto an array of a hash?如何将哈希中的值推送到哈希数组中?
【发布时间】:2017-08-01 10:02:58
【问题描述】:

我有一个 %hashmap 和一个数组 @values

在我的代码中,%hashmap 是这样创建的 $hashmap{$key}="$name";

创建%hashmap 后,我需要获取它的值并将其添加到相同的%hashmap 但使用不同的键,新的哈希图如下所示:

@hashvalues=($name,$type,$Statement,\@parents,\@children)
$hashmap{$newkey}=\@hashvalues;

我想将$name$hashmap{$key}推入\@children$hashmap{$newkey}

这是我目前的代码:

# first i check if the $hashmap exists so i know i update it 

if(exists$hashmap{$name}){
    my $auxiliary=\@{$hashmap{$name}};
    push(@children,@$auxiliary);
}   
my @hashvalues=($name,$type,$Statement,\@parents,\@children);

$hashmap{$name}=\@hashvalues;

%hash我想push是在这里创建的,没有其他记录了:

if ($parent ne @$hashvalues2[0]) {      
    $hashmap{$parent}="$child";
}

我有兴趣存储和推送的值是$child这里。

这里将再次创建相同的 %hash,但使用字段名称、类型等:(不是空字段!,它们都有之前分配的值)

@hashvalues = ($name, $type, $Statement, \@parents, \@children)
$hashmap{$newkey} = \@hashvalues; 

我想看看 %hash 是否是在此之前创建的 @hasvalues=($name..

所以我用这段代码检查它:

if (exists$hashmap{$name}) { Do Code... }

如果有记录,我想更新 %hash ,方法是在 @hashvalues\@parents 中推送值 $child ,所以当 %hash 具有类型时,将生成名称 ..拥有它以前版本的 $child 值。

这是代码的顺序:

  1. if (exists$hashmap{$name}) { Do Code; }

  2.  

    my @hashvalues  = ($name, $type, $Statement, \@parents, \@children);
    $hashmap{$name} = \@hashvalues;
    
  3.  

    if ($parent ne @$hashvalues2[0]) {
        $hashmap{$parent} = "$child";
    }
    

这是完整的代码:

@FileStatements - 语句数组 $Statement - 一个更大的字符串,我从中收集所有数据

然后我用我收集的所有数据填写@hashvalues

my $FROMduplicate="";
 my $JOINduplicate="";
    foreach my $Statement (@FileStatements) {

        if ($Statement!~m/create/i) {
            next;
        }
        if ($Statement=~m/create user |^GRANT |^spool /gim) {
            next;       
        }
        my $name="";
        my $type="";
        my $content="";#FileStatements
        my @parents=();
        my @children=();
        my $duplicate="";
        # print $Statement."\n";

    #NAME--------------------------------------------
        my $catch = (split(/ view | trigger | table | synonym | procedure | role /i, $Statement))[1];
        $catch =~ s/^\s+//;
        $name = (split(/\s+/, $catch))[0];
        if ($name=~m/undef/gi){next;}
    #DEBUG  #print "$name\n";
    #TYPE--------------------------------------------
        if( $Statement=~m/^create or replace \w+ /i) {
        my $tmp = (split(/ replace /i, $Statement))[1];
        $tmp =~ s/^\s+//;
        $type = (split(/\s+/, $tmp))[0];
        }
        else{

        my $tmp = (split(/^create /i, $Statement))[1];  
        $tmp =~ s/^\s+//;
        $type = (split(/\s+/, $tmp))[0];
        }
        if ($type=~m/undef| undef |\s+undef\s+|\s+undef,/) {
            next;
        }

            #print "$type\n";
        #CONTENT-----------------------------------------
        #PARENTS-----------------------------------------
        my @froms = split(/ from\s+/i, $Statement); 
        my @joins = split(/ join /i, $Statement);
        foreach my $i (1..@froms-1) {
            #print Writer1 "$froms[$i]"."\n\n";
            my $from = (split(/ where |select | left |  left | right | as /i, $froms[$i])) [0];
            $from=~s/^\s+//;
            $from=~s/\(+//;
            my @Spaces = split(/, | , /,$from);
            foreach my $x (0..@Spaces-1) {
                    my $SpaceFrom = (split(/ /,$Spaces[$x])) [0];
                    $SpaceFrom=~s/;//;
                    $SpaceFrom=~s/\)+//;
                # print Writer1 $SpaceFrom."\n\n";
                    if ($SpaceFrom eq $FROMduplicate) {
                        next;
                    }
                    push(@parents,$SpaceFrom);                 
                     $FROMduplicate=$SpaceFrom;
           }  
        }
        foreach my $x (1..@joins-1){
            #print "$joins[$i]"."\n\n";
            my $join = (split(/ on /i,$joins[$x])) [0];
            $join = (split(/ /i,$joins[$x])) [0];
            #print Writer "\n\n".$join."\n\n";   
             if ($join eq $JOINduplicate) {
                next;
             }
            push(@parents,$join);
              $JOINduplicate=$join;

        }
             @parents = do { my %seen; grep { !$seen{$_}++ } @parents };
        #check hash for existence
           if(exists$hashmap{$name}){


             push(@{$hashmap[3]},@parents);
             push(@{$hashmap[0]},$name);
             push(@{$hashmap[1]},$type);
             push(@{$hashmap[2]},$Statement);
            }

        my @hashvalues=($name,$type,$Statement,\@parents,\@children);
        $hashmap{$name}=\@hashvalues;
         # push(@children,$hashmap{$name}) if( exists$hashmap{$name})   

    } 

}

【问题讨论】:

  • 数组@hashvalues从何而来?我在这里的任何地方都看不到“哈希数组”。一个真实数据的例子会有很大帮助。
  • 过于粗体和可怕的格式使其他人难以阅读您的问题。

标签: perl data-structures reference hashmap


【解决方案1】:

你的问题还不清楚,但我想我可以断章取义地回答这个问题

我想将 $hashmap{$key} 中的 $name 推送到 $hashmap{$newkey}\@children

我假设你已经有了类似的东西

my %hashmap;

my ( $name, $type, $Statement, @parents, @children );

my @hashvalues = ( $name, $type, $Statement, \@parents, \@children );
$hashmap{$newkey} = \@hashvalues;
  • 请记住,标识符nametypeStatement 等已经消失,这五个值只是数组的元素

  • $hashmap{$key} 中的 $name 是数组的第一个元素,所以它是 $hashmap{$key}[0]

  • $hashmap{$newkey}@children 是数组的第五个元素,或者 $hashmap{$newkey}[4]

  • 要将第一个推入第二个,您需要

    push @{ $hashmap{$newkey}[4] }, $hashmap{$key}[0]
    

您还应该使用比hashmap 更有意义的东西作为您的标识符。 % 表示该变量是一个哈希(没有 Perl 哈希映射之类的东西),您应该使用该名称来描述其内容的性质

【讨论】:

    猜你喜欢
    • 2011-09-01
    • 1970-01-01
    • 2016-06-27
    • 2016-05-16
    • 2020-07-24
    • 2011-04-20
    • 2017-02-19
    • 2015-11-28
    • 2017-01-04
    相关资源
    最近更新 更多