代码之家  ›  专栏  ›  技术社区  ›  TheAdam122

如何在Perl中将字符串拆分为多个哈希键

  •  1
  • TheAdam122  · 技术社区  · 7 年前

    例如,我有一系列字符串

    my @strings;
    $strings[1] = 'foo/bar/some/more';
    $strings[2] = 'also/some/stuff';
    $strings[3] = 'this/can/have/way/too/many/substrings';
    

    我要做的是拆分这些字符串并将它们作为这样的键存储在哈希中

    my %hash;
    $hash{foo}{bar}{some}{more} = 1;
    $hash{also}{some}{stuff} = 1;
    $hash{this}{can}{have}{way}{too}{many}{substrings} = 1;
    

    我可以继续列出我失败的尝试,但我不认为它们会增加问题的价值,但我会提到一个。假设我改变了 'foo/bar/some/more' '{foo}{bar}{some}{more}' . 我可以把它存储在一个变量中,然后做如下的事情吗?

    my $var = '{foo}{bar}{some}{more}';
    $hash$var = 1;
    

    注意:这不起作用,但我希望它只是因为语法错误。

    感谢所有帮助。

    4 回复  |  直到 7 年前
        1
  •  5
  •   Dave Cross    7 年前

    与肖恩的回答逻辑相同。但我把聪明的hash walking位隐藏在子例程中。我已经将最终值设置为1,而不是空的哈希引用。

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use feature 'say';
    
    use Data::Dumper;
    
    my @keys = qw(
      foo/bar/some/more
      also/some/stuff
      this/can/have/way/too/many/substrings
    );
    
    my %hash;
    
    for (@keys) {
      multilevel(\%hash, $_);
    }
    
    say Dumper \%hash;
    
    sub multilevel {
      my ($hashref, $string) = @_;
    
      my $curr_ref = $hashref;
      my @strings = split m[/], $string;
      for (@strings[0 .. $#strings - 1]) {
        $curr_ref->{$_} //= {};
        $curr_ref = $curr_ref->{$_};
      }
    
      $curr_ref->{@strings[-1]} = 1;
    }
    
        2
  •  4
  •   shawnhcorey    7 年前

    您必须使用哈希引用遍历键列表。

    use Data::Dumper;
    
    my %hash = ();
    
    while( my $string = <DATA> ){
        chomp $string;
        my @keys = split /\//, $string;
        my $hash_ref = \%hash;
        for my $key ( @keys ){
            $hash_ref->{$key} = {};
            $hash_ref = $hash_ref->{$key};
        }
    }
    say Dumper \%hash;
    
    __DATA__
    foo/bar/some/more
    also/some/stuff
    this/can/have/way/too/many/substrings
    
        3
  •  0
  •   daxim Fayland Lam    7 年前

    用图书馆就行了。

    use Data::Diver qw(DiveVal);
    my @strings = (
        undef,
        'foo/bar/some/more',
        'also/some/stuff',
        'this/can/have/way/too/many/substrings',
    );
    my %hash;
    for my $index (1..3) {
        my $root = {};
        DiveVal($root, split '/', $strings[$index]) = 1;
        %hash = (%hash, %$root);
    }
    __END__
    (
        also => {some => {stuff => 1}},
        foo  => {bar => {some => {more => 1}}},
        this => {can => {have => {way => {too => {many => {substrings => 1}}}}}},
    )
    
        4
  •  0
  •   user10096506    7 年前

    我走了一条简单的路,从“eval”出来:

    use Data::Dumper;
    
    %hash = ();
    @strings = ( 'this/is/a/path', 'and/another/path', 'and/one/final/path' );
    foreach ( @strings ) {
        s/\//\}\{/g;
        $str = '{' . $_ . '}';      # version 2: remove this line, and then
        eval( "\$hash$str = 1;" );  #   eval( "\$hash{$_} = 1;" );
    }
    
    print Dumper( %hash )."\n";
    
    推荐文章