【问题标题】:Strange behaviour from push (hash)推送(哈希)的奇怪行为
【发布时间】:2018-05-21 14:43:05
【问题描述】:

我完全理解哈希是未排序的,但我的印象是它始终保持键/值关系。

我根本不理解这种行为。当我从数组推送时,进行一些重复数据删除,然后打印键、子键和值,我得到了想要的结果:

my @Input = ("Crockery breakable plates",
             "Crockery breakable glasses",
             "Cutlery bendable forks",
             "Cutlery bendable spoons"
            );

my %store = ();
foreach (@Input) {
    my ($key, $key2, $value) = split;
    chomp ($key, $key2, $value);
    my $combine = "$key-$key2-$value";
    push @arr, "$key-$key2-$value";
   # push @{$store{$combine}}, "$key-$key2-$value";
 }

foreach (@arr) {
($key, $key2, $value) =split /-/;
 chomp ($key, $key2, $value);
     $seen{$key}++ || print "1. $key\n";
      $seen{$key2}++ || print "2. -- $key2\n";
       $seen{$value}++ || print "3. ----$value\n";
    }

每次都会打印出来:

1. Crockery
2. -- breakable
3. ----plates
3. ----glasses
1. Cutlery
2. -- bendable
3. ----forks
3. ----spoons

然后我基本上做同样的事情,但推到

my @Input = ("Crockery breakable plates",
             "Crockery breakable glasses",
             "Cutlery bendable forks",
             "Cutlery bendable spoons"
            );

my %store = ();
foreach (@Input) {
    my ($key, $key2, $value) = split;
    chomp ($key, $key2, $value);
    my $combine = "$key-$key2-$value";
   # push @arr, "$key-$key2-$value";
    push @{$store{$combine}}, "$key-$key2-$value";
 }

foreach my $k(keys %store) {
    ($key, $key2, $value) = split /-/, $k;
    chomp ($key, $key2, $value);
         $seen{$key}++ || print "1. $key\n";
          $seen{$key2}++ || print "2. -- $key2\n";
           $seen{$value}++ || print "3. ----$value\n";
    }

每次打印随机结果:

1. Cutlery
2. -- bendable
3. ----forks
1. Crockery
2. -- breakable
3. ----plates   
3. ----spoons    < --- not Crockery
3. ----glasses

这里唯一真正的区别(我可以看到)是我拆分了键名,但该布局仍然与数组名相同。

所以问题是,有人可以帮助我理解为什么以及如何解决这个问题吗?

PS!!我问这个问题的原因是,我想在我的脚本中拆分我的键名,而不是推送另一个数组,因为我已经推送了一次这个键名,因为我在脚本的另一部分使用它。

【问题讨论】:

    标签: perl


    【解决方案1】:

    $seen{something}++ || print ... 结构中删除||,你会看到输出是正确的。

    ...
    foreach my $k(keys %store) {
      ($key, $key2, $value) = split /-/, $k;
      chomp ($key, $key2, $value);
      $seen{$key}++ && print "*"; print "1. $key\n";
      $seen{$key2}++ && print "*"; print "2. -- $key2\n";
      $seen{$value}++ && print "*"; print "3. ----$value\n";
    }
    

    1. Cutlery
    2. -- bendable
    3. ----forks
    1. Crockery
    2. -- breakable
    3. ----glasses
    *1. Cutlery
    *2. -- bendable
    3. ----spoons
    *1. Crockery
    *2. -- breakable
    3. ----plates
    

    新脚本中以* 开头的任何行都不会在原始脚本中输出。


    请注意,如果您对%store 的键进行排序,则第二个键和值将始终与正确的第一个键相关联,如您所愿:

    foreach my $k (sort keys %store) {
    #              ^^^^
         ($key, $key2, $value) = split /-/, $k;
         chomp ($key, $key2, $value);
         $seen{$key}++ || print "1. $key\n";
         $seen{$key2}++ || print "2. -- $key2\n";
         $seen{$value}++ || print "3. ----$value\n";
    }
    

    1. Crockery
    2. -- breakable
    3. ----glasses
    3. ----plates
    1. Cutlery
    2. -- bendable
    3. ----forks
    3. ----spoons
    

    虽然我猜如果同一个值或 key2 与多个键相关联,您仍然会感到困惑。

    【讨论】:

    • 完美,这很有意义,感谢磨坊。同时投了赞成票,因为我必须再等 4 分钟才能将答案标记为正确。
    • sort 选项正是我所需要的,非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多