【问题标题】:How to assign array variable as a hash?如何将数组变量分配为哈希?
【发布时间】:2018-06-10 17:14:03
【问题描述】:

我正在尝试打印此哈希。因为key1array[0]key2array[2]$sum[0] 是值。但是已经不起作用了。我做错了什么?

@array=(10,45,20);

@sum=($array[0]+$array[1]+$array[2]);

%hash;

$hash{$array[0]}{$array[2]}=$sum[0]

在哈希的末尾,我想将10 : 75 打印到屏幕上。

【问题讨论】:

  • 请始终将use strict; use warnings; 添加到您的脚本中以避免常见错误。 /// 你的问题到底是什么?您创建了一个包含{ '10' => { '20' => 75 } } 的哈希。想要什么?
  • 在哈希的末尾我想在屏幕上打印 10 : 75 但我不知道如何给出这个哈希的参考..
  • 那你为什么要使用二维散列呢?为什么不简单地$hash{$array[0]}=$sum[0]?这给了{ '10' => 75 }
  • 是的,我知道。我从文本中获取值并放置一个数组。然后使这个数组成为一个二维散列,其中包含两个键,数组的第一个元素是第一个键,第二个元素作为第二个键.然后我要打印它。这就是我想要做的..
  • 欢迎来到计算机编程的世界! --- 你可能已经注意到 Borodin 和 ikegami 试图帮助你解决一个不完整的问题描述。通常这两个人非常善于从半个问题中理解问题,并愿意带你通过步骤来澄清事情。 --- 而且我愚蠢到可以再试一次 - 我知道比他们好!!!

标签: arrays perl multidimensional-array hash key


【解决方案1】:

你已经设置了

$hash{$array[0]}{$array[2]} = $sum[0]

具有给定值的是

$hash{10}{20} = 75

如果你想从哈希中打印10 : 75,那么你需要写

printf "%d : %d\n",10, $hash{10}{20}

虽然我确定你想要比这更笼统的东西,但你确实没有提供足够的信息

【讨论】:

  • 是的,我可以这样做,但我想将它用于大文件,所以我不能像这样写哈希,我必须为键写数组 [1] 和数组 [2] .. .我怎么能这样接受..?
  • 认为我有一个包含 chris 10 34 56 值的文件。我想将 tehm 作为一个数组,然后用两个键创建两个 dimensinol 散列。作为 chris=first 键和数字总和=second key 然后我想打印 chris=sum of tree numbers ..
  • @Fatih:是的,我想你有不止一行数据,但你的例子过于琐碎。如果你只显示一行,那么我们看不到它应该如何缩放。请再显示几行数据以及您想要的相应输出。如果发送密钥 20 从未使用过,则没有理由将其存储在哈希中。
  • @Faith:你真的需要解释为什么你认为你需要$array[2] 作为哈希键。在您的代码中,数字的总和就是 哈希值,看起来您只需要一个键。
  • @Fatih:错了。但不可能说出您的真正要求是什么,因为您不会向我们提供任何信息。我投票结束你的问题。
【解决方案2】:

根据您给@ikegami «我的程序将接受...» 的描述,我创建了一个包含数据的文件:

data_1.txt

john 10 45 20
alex 30 15 12
pete 23 45 10 21
will 06 56
bob   8 12  3
lazy 

请注意,只有前两行实际上与描述相符,我稍后再讨论。

sum.pl

use strict;
use warnings;

use List::Util 'sum';

# get the two filenames it should work with
#
my $filename_1 = shift;
my $filename_2 = shift;

# be sure we read a file for most modern systems, UTF-8
#
open( my $file1, '<:encoding(UTF-8)', $filename_1)
    or die "Can't open file: $filename_1";

# create the (empty) data structure
#
my %sums_and_names;
#
# the % in perl means you are talking about a hash,
# use a sensible name instead of 'hash'

# read line by line
while ( my $line = <$file1> ) {

    chomp $line; # get rid of the line endings
    my ($name, @grades) = split ' ', $line;
    #
    # this is not strictly doing what you asked for, just more flexible
    #
    # split on ' ', a space character, splits on any asmount of (white) space
    # your task said that there is one space.
    # strictly, you could should split on / /, the regular expression
    #
    # the first part will go into the variable $name, the rest in array @grades
    # strictly you have only three grades so the following would do
    # my ($name, $grade_1, $grade_2, $grade_3) = split / /, $line;

    my $sum = sum(@grades) // 'no grades';
    #
    # since we now can handle any number of grades, not just three, we could
    # have no grades at all and thus result in `undef`
    #
    # using the function sum0 would return the value 0 instead
    #
    # you'll get away with the `undef` using in a hash assignment,
    # it will turn it into an empty string `''`

=pod

    $sums_and_names{foo}{bar} = [ 'baz', 'qux' ];

=cut

    #
    # here is where your task doesn't make sense
    # i am guessing:
    #
    $sums_and_names{$sum}{$name} = \@grades;
    #
    # at least we have all the data from filename_1, and the sum of the grades

}

# please decide on what you want to print

use Data::Dumper;
print Dumper \%sums_and_names;

运行 perl sum.pl data_1.txt data_2.txt 会给你类似的东西

输出

$VAR1 = {
          'no grades' => {
                    'lazy' => []
                         },
          '23' => {
                    'bob'  => [
                                '8',
                                '12',
                                '3'
                              ]
                  },
          '57' => {
                    'alex' => [
                                '30',
                                '15',
                                '12'
                              ]
                  },
          '62' => {
                    'will' => [
                                '06',
                                '56'
                              ]
                  },
          '75' => {
                    'john' => [
                                '10',
                                '45',
                                '20'
                              ]
                  },
          '99' => {
                    'pete' => [
                                 '23',
                                 '45',
                                 '10',
                                 '21'
                               ]
                   }
        };

请注意,严格来说,while循环内的块可以写成:

    chomp $line;
    my ($name, $grade_1, $grade_2, $grade_3) = split / /, $line;
    $sum = $grade_1 + $grade_2 + $grade_3;
    $sums_and_names{$sum}{$name} = [ $grade_1, $grade_2, $grade_3 ];

但我引用@Borodin:

虽然我确定你想要比这更笼统的东西,但你确实没有提供足够的信息

【讨论】:

  • 你不使用$filename_2。不过,我不认为这有什么不同。完全不清楚 OP 真正想要什么数据结构,他的 cmets 也无济于事。例如,我现在认为他要求的结构是$sums_and_names{$name}{$sum}(交换了键)。我们只是不知道。他应该显示所需的输出(以 Data::Dumper 或 JSON 格式),但他拒绝了。
  • 当然我知道我没有使用$filename_2,但这就是他在最后的描述中所说的“......接受两个未排序的文件。” --- 我故意把它留在那里并试图表明这是一个描述得很糟糕的问题,并且 OP 应该重新考虑他下次如何问它。 --- 实际上,我可以添加一些检查是否确实传递了两个文件名
  • 是的,我的文档与它完全相同。抱歉,我无法共享代码,因为我没有权限。我只是不明白我做错了什么,用你的例子我明白了。谢谢。我给出的哈希引用不是一个值。
【解决方案3】:
  • 始终使用use strict; use warnings qw( all );!!!
  • (一次)只有一个总和,因此不需要数组。
  • 不需要散列的散列;一个简单的哈希就可以了。

固定:

use strict;
use warnings qw( all );

use List::Util qw( sum );


my %hash;
while (...) {
   my @nums = ...;
   $hash{ $nums[0] } = sum(@nums);
}

for (sort { $a <=> $b } keys(%hash)) {
   print("$_: $hash{$_}\n");
}

【讨论】:

  • 感谢您的关注,但我已经用一把钥匙完成了,我也想用两把钥匙创建..您的代码只有一把钥匙..
  • 应该如此。创建比所需更复杂的数据结构是没有意义的。
  • chris : HASH(0x5581f6193078) 我的输出看起来就像我写的一样,为什么要让我得到哈希结果..
  • 我的程序将接受两个未排序的文件。每个文件包含用空格分隔的 4 列。第一列是名称(字符串)。其余列(3 列)是代表成绩的整数。将第一个文件加载到二维散列数据结构中,整数之和(总成绩)作为第二维键,名称
  • 如果您的问题有问题,请解决。完成后,请随时在此处发表评论告诉我。
猜你喜欢
  • 2011-07-20
  • 2017-09-03
  • 2015-11-26
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2012-10-29
相关资源
最近更新 更多