Creating hash using array value 使用数组值创建哈希

huangapple go评论59阅读模式
英文:

Perl : Creating hash using array value

问题

我对perl还有点陌生,正在处理一个小脚本,基本上是读取一个包含时间表的文件,格式有点不规范,类似于 -

Test/Month/January
Test/Month/February
Mock/Month/August
Practical/Month/June
Result/Month/October


基本上我想要读取它并创建一个哈希表,根据事件(Test/Mock/Practical/Result)进行分组,值将保持为一个数组。因此,对于上面的文件,当我运行我的脚本时,它应该输出以下哈希表 -

{
Timetable => { 'Test' => ['January', 'February'], 'Mock' => ['August'], 'Practical' => ['June'], 'Result' => ['October'] }
}


Timetable 将是外部的哈希表,其中包含了所有的数据。建议和帮助将不胜感激。
英文:

I'm bit new to perl and working on a small script which basically reads a file having timelines in a slightly unstructured manner something like -

Test/Month/January
Test/Month/February
Mock/Month/August
Practical/Month/June
Result/Month/October

Basically I want to read it and frame a hash which will be segregated based on the events(Test/Mock/Practical/Result) and the values will be maintained as an array. So for the above file when I run my script it should output the following hash -

{
    Timetable => { 'Test' => ['January', 'February'], 'Mock' => ['August'], 'Practical' => ['June'], 'Result' => ['October'] } 
}

Timetable will be the outer hash which will have the whole data. Suggestions and help is appreciated.

答案1

得分: 2

一个可能的解决方案是读取每一行并根据 / 进行分割,检查返回的数组中是否有 3 个元素,然后检查中间的元素是否等于 Month。如果是这样,将最后一个元素推入一个数组中,该数组通过第一个元素在哈希变量中进行映射。

示例:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my %H; # 第一个元素是键 - 映射到一个数组

while(<>) {
    chomp;
    @_ = split(m:/:,$_); # Test/Month/January

    # 检查是否有 3 个元素,并且中间元素是 `Month`,然后推入映射的数组中:
    push @{$H{$_[0]}}, $_[2] if(@_ == 3 && $_[1] eq 'Month');
}

print Dumper(\%H);

输出:

$VAR1 = {
          'Practical' => [
                           'June'
                         ],
          'Test' => [
                      'January',
                      'February'
                    ],
          'Result' => [
                        'October'
                      ],
          'Mock' => [
                      'August'
                    ]
        };
英文:

One possible solution would be to read each line and split on /, check that there are 3 elements in the returned array and then check that the middle element is equal to Month. If so, push the last element into an array which is mapped via the first element in a hash varible.

Example:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my %H; # first element is key - map to an array

while(&lt;&gt;) {
    chomp;
    @_ = split(m:/:,$_); # Test/Month/January

    # check that there are 3 elements and that the middle is `Month`
    # then push to the mapped array:
    push @{$H{$_[0]}}, $_[2] if(@_ == 3 &amp;&amp; $_[1] eq &#39;Month&#39;);
}

print Dumper(\%H);

Output:

$VAR1 = {
          &#39;Practical&#39; =&gt; [
                           &#39;June&#39;
                         ],
          &#39;Test&#39; =&gt; [
                      &#39;January&#39;,
                      &#39;February&#39;
                    ],
          &#39;Result&#39; =&gt; [
                        &#39;October&#39;
                      ],
          &#39;Mock&#39; =&gt; [
                      &#39;August&#39;
                    ]
        };

答案2

得分: 2

以下是翻译好的部分:

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my %hash;

while(<DATA>){
        chomp $_;
        my @data = split("/", $_);
        push (@{$hash{$data[0]}}, $data[2]);
}

print Dumper(\%hash);

__DATA__
Test/Month/January
Test/Month/February
Mock/Month/August
Practical/Month/June
Result/Month/October

结果:

$VAR1 = {
          'Practical' => [
                           'June'
                         ],
          'Result' => [
                        'October'
                      ],
          'Test' => [
                      'January',
                      'February'
                    ],
          'Mock' => [
                      'August'
                    ]
        };
英文:

See the below script, which would help you.

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my %hash;

while(&lt;DATA&gt;){
        chomp $_;
        my @data = split(&quot;/&quot;, $_);
        push (@{$hash{$data[0]}}, $data[2]);
}

print Dumper(\%hash);

__DATA__
Test/Month/January
Test/Month/February
Mock/Month/August
Practical/Month/June
Result/Month/October

Result:

$VAR1 = {
          &#39;Practical&#39; =&gt; [
                           &#39;June&#39;
                         ],
          &#39;Result&#39; =&gt; [
                        &#39;October&#39;
                      ],
          &#39;Test&#39; =&gt; [
                      &#39;January&#39;,
                      &#39;February&#39;
                    ],
          &#39;Mock&#39; =&gt; [
                      &#39;August&#39;
                    ]
        };

答案3

得分: 1

你只需按行读取输入,将每行按/Month/拆分,然后将月份推送到存储在哈希中的事件键下的匿名数组中。

#!/usr/bin/perl
use warnings;
use strict;

my $h;
while (<>) {
    chomp;
    my ($event, $month) = split m{/Month/};
    push @{ $h->{Timetable}{$event} }, $month;
}
英文:

You can just read the input line by line, split each line on /Month/ and push the month to an anonymous array stored under the event key in a hash.

#!/usr/bin/perl
use warnings;
use strict;

my $h;
while (&lt;&gt;) {
    chomp;
    my ($event, $month) = split m{/Month/};
    push @{ $h-&gt;{Timetable}{$event} }, $month;
}

huangapple
  • 本文由 发表于 2023年5月17日 20:40:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76272221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定