【问题标题】:array to hash in perlperl 中要散列的数组
【发布时间】:2011-03-13 01:37:31
【问题描述】:

我有一个源列表,我从中挑选随机项目并填充目标列表。列表中的项目具有特定的格式。例如:

item1{'name'}
item1{'date'}

等等以及更多领域。

在插入目标列表时,我会检查项目上的唯一名称并将其插入到该列表中。为此,我必须遍历整个目标列表以检查具有给定名称的项目是否存在,如果不存在则插入它。

我认为如果我将目标列表再次设为哈希而不是列表会很好,这样我就可以更快更有效地查找项目。我是 Perl 的新手,不知道如何做到这一点。任何人,请帮助我如何插入项目,查找特定项目名称,并删除哈希中的项目?

如何将名称和日期作为键,将整个项目作为值?

【问题讨论】:

标签: perl arrays hash scripting


【解决方案1】:

我的 %hash;

  1. 使用键 $K 插入项目 $V?

    $hash{$K} = $V

  2. 查找特定名称/密钥 $K?

如果(存在 $hash{$K}){ print "它在那里,价值 '$hash{$K}'\n"; } 别的 { print "它不在里面\n" }
  1. 删除特定名称/键?

    删除$hash{$K}

  2. 将姓名和日期设为键,将整个项目设为值?

简单的方法:把所有东西串起来

set: $hash{ "$name:$date" } = "$name:$date:$field1:$field2"
get: my ($name2,$date2,$field1,$field2) = split ':', $hash{ "$name:$date" }
del: delete $hash{ "$name:$date" }

更难的方式:在散列中存储为散列(谷歌“perl 对象”)

设置:

my %temp;
$temp{"name"} = $name;
$temp{"date"} = $date;
$temp{"field1"} = $field1;
$temp{"field2"} = $field2

$hash{"$name:$date"} = \$temp;

得到:

my $find = exists $hash{"$name:$date"} ? $hash{"$name:$date"} : undef;
if (defined find) { # i.e. it was found
    printf "field 1 is %s\n", $find->{"field1"}
} else {
    print "Not found\n";
}

删除:

delete $hash{"$name:$date"}

【讨论】:

  • 如果您的数据中包含冒号,“简单方法”将成为“困难方法”。
  • 幸运的是数据不包含冒号。非常感谢。这有效:)
  • 同意,不建议使用简单的方法。你最好在冒号上使用空字节\0,但即使这样也不建议。
【解决方案2】:

由于您没有具体描述输入和所需的输出,因此很难理解您的要求。

我最好的猜测是:

#!/usr/bin/perl

use strict; use warnings;

my @list = (
    q(item1{'name'}),
    q(item1{'date'}),
);

my %lookup;

for my $entry ( @list ) {
    my ($name, $attrib) = $entry =~ /([^{]+){'([^']+)'}/;
    $lookup{ $name }{ $attrib } = $entry;
}

for my $entry ( keys %lookup ) {
    my %entry = %{ $lookup{$entry} };
    print "@entry{keys %entry}\n"
}

use YAML;
print Dump \%lookup;

输出:

item1{'date'} item1{'name'}
---
项目1:
  日期:“item1{'date'}”
  名称:“item1{'name'}”

【讨论】:

    【解决方案3】:

    如果您知道您将需要哪些物品以及您需要它们的顺序 对于键,然后重新解析键的价值值得怀疑。我更喜欢存储 他们在水平。

    $hash{ $h->{name} }{ $h->{date} } = $h;
    # ... OR ...
    $hash{ $h->{date} }{ $h->{name} } = $h;
    
    foreach my $name ( sort keys %hash ) { 
        my $name_hash = $hash{$name};
        foreach my $date ( keys %$name_hash ) { 
            print "\$hash{$name}{$date} => " . Dumper( $name_hash->{$date} ) . "\n";
        }
    }
    

    对于任意级别,您可能需要一个遍历函数

    sub traverse_hash (&@) { 
        my ( $block, $hash_ref, $path ) = @_;
        $path = [] unless $path;
        my ( @res, @results );
        my $want           = wantarray;
        my $want_something = defined $want;
    
        foreach my $key ( %$hash_ref ) { 
            my $l_path = [ @$path, $key ];
            my $value  = $hash_ref->{$key};
            if ( ref( $value ) eq 'HASH' ) { 
                @res = traverse_hash( $block, $value, $l_path );
                push @results, @res if $want_something && @res;
            }
            elsif ( $want_something ) {
                @res = $block->( $l_path, $value );
                push @results, @res if @res;
            }
            else { 
                $block->( $path, $value );
            }
        }
        return unless $want_something;
        return $want ? @results : { @results };
    }
    

    所以这和上面做的一样:

    traverse_hash {
        my ( $key_path, $value ) = @_;
        print( '$hash{' . join( '}{', @$key_path ) . '} => ' . ref Dumper( $value ));
        ();
    } \%hash
    ;
    

    【讨论】:

      【解决方案4】:

      Perl 解决方案


      #!/usr/bin/perl -w
      
      use strict;
      use Data::Dumper;
      
         sub main{
            my %hash;
            my @keys = qw(firstname lastname age);                    # hash's keys
            
            
                        #  fname    lname    age
                        # --------|--------|-----
            my @arr  = ( [ 'foo1',  'bar1',  '1' ],
                         [ 'foo2',  'bar2',  '2' ],
                         [ 'foo3',  'bar3',  '3' ]
                       );
                       
            # test if array set up correctly
            print "\$arr[1][1]       : $arr[1][1] \n";                # bar2      
      
          
            # loads the multidimensional array into the hash
            for my $row (0..$#arr){
               for my $col ( 0..$#{$arr[$row]} ){
                  my $itemnum = "item" . ($row+1);                    # using the item# format you used
                  $hash{$itemnum}->{$keys[$col]} = $arr[$row][$col];
               }
            }
            
            # manually add a 4th item
            $hash{item4} = {"firstname", "foo", "lastname", "bar", "age", "35"};
            
            
            
            # How to Retrieve
            # -----------------------
            
            # single item pull
            print "item1->firstname : $hash{item1}->{firstname} \n";  # foo1
            print "item3->age       : $hash{item3}->{age}       \n";  # 3
      
            # whole line 1
            {  local $, = " "; 
               print "full line        :" , %{$hash{item2}} , "\n";   # firstname foo2 lastname bar2 age 2 
            } 
            
            # whole line 2
            foreach my $key (sort keys %{$hash{item2}}){
               print "$key   : $hash{item2}{$key} \n";
            }
            
            
            # Clearer description
            #print "Hash:\n", Dumper %hash;
         }
         
         main();
      

      除了接受的答案之外,还应该使用它。您的问题对array to hash 的要求有点含糊,也许这就是您要寻找的模型?

      【讨论】:

        猜你喜欢
        • 2021-08-22
        • 1970-01-01
        • 2012-08-03
        • 2014-05-19
        • 2012-06-12
        • 2017-02-21
        • 2014-01-16
        • 2010-12-31
        • 2016-08-03
        相关资源
        最近更新 更多