【问题标题】:Separating CSV file into key and array将 CSV 文件分离为键和数组
【发布时间】:2015-11-24 02:28:27
【问题描述】:

我是 perl 的新手,我正在尝试将一个 csv 文件(每行有 10 个逗号分隔的项目)分成一个键(第一个项目)和一个数组(9 个项目)以放入哈希中。最终,我想使用if 函数将另一个变量与哈希中的键匹配并打印出数组中的元素。

这是我的代码,它不能正常工作。

use strict;
use warnings;

my %hash;

my $in2 = "metadata1.csv";
open IN2, "<$in2" or die "Cannot open the file: $!";
while (my $line = <IN2>) {
    my ($key, @value) = split (/,/, $line, 2);
    %hash = (
    $key => @value
);
}

foreach my $key (keys %hash)
{
  print "The key is $key and the array is $hash{$key}\n";
}

感谢您的帮助!

【问题讨论】:

    标签: arrays perl


    【解决方案1】:

    不要使用 2 作为split 的第三个参数:它会将行拆分为只有两个元素,所以只有一个@value。

    此外,通过执行%hash =,您将在循环的每次迭代中覆盖散列。只需添加一个新的键/值对:

    $hash{$key} = \@value;
    

    注意\ 符号:您不能将数组直接存储为哈希值,您必须存储对它的引用。打印值时,您必须取消引用它:

    #! /usr/bin/perl
    use warnings;
    use strict;
    
    my %hash;
    while (<DATA>) {
        my ($key, @values) = split /,/;
        $hash{$key} = \@values;
    }
    
    for my $key (keys %hash) {
        print "$key => @{ $hash{$key} }";
    }
    
    __DATA__
    id0,1,2,a
    id1,3,4,b
    id2,5,6,c
    

    如果您的 CSV 文件包含引号或转义逗号,您应该使用 Text::CSV

    【讨论】:

    • 嗨!谢谢您的回答。我覆盖哈希是有道理的,因为它在循环中。我使用了你的建议 - 它打印了密钥,但它说数组是 ARRAY (0x7fa530852108) (不在 CSV 文件中的任何位置) - CSV 文件的第一行是 NAME,GENDER,AGE,HOMETOWN,HOMESTATE,当前状态、教育、教育年限、职业、种族。我只是不知道 perl 从哪里得到“ARRAY (0x7fa530852108)”。
    【解决方案2】:

    首先,哈希只能有一个唯一键,所以当你的 CSV 文件中有这样的行时:

    key1,val11,val12,val13,val14,val15,val16,val17,val18,val19
    key1,val21,val22,val23,val24,val25,val26,val27,val28,val29
    

    将带有“key1”键的两个键/值对添加到哈希后,您将只得到一对保存在哈希中,即稍后添加到哈希中的一对。

    所以要保留所有记录,你可能需要哈希数组的结果结构,其中每个哈希的值是一个数组引用,像这样:

    @result = (
        { 'key1' => ['val11','val12','val13','val14','val15','val16','val17','val18','val19'] },
        { 'key1' => ['val21','val22','val23','val24','val25','val26','val27','val28','val29'] },
        { 'and'  => ['so on'] },
    );
    

    为了实现你的代码应该变成这样:

    use strict;
    use warnings;
    
    my @AoH;        # array of hashes containing data from CSV
    
    my $in2 = "metadata1.csv";
    open IN2, "<$in2" or die "Cannot open the file: $!";
    while (my $line = <IN2>) {
        my @string_bits = split (/,/, $line);
        my $key = $string_bits[0];                          # first element - key
        my $value = [ @string_bits[1 .. $#string_bits] ];   # rest get into arr ref
    
        push @AoH, {$key => $value};        # array of hashes structure
    }
    
    foreach my $hash_ref (@AoH)
    {
        my $key = (keys %$hash_ref)[0];                     # get hash key
        my $value = join ', ', @{ $hash_ref->{$key} };      # join array into str
        print "The key is '$key' and the array is '$value'\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2014-10-19
      • 2016-04-15
      • 1970-01-01
      相关资源
      最近更新 更多