CSV в хэш - PullRequest
       34

CSV в хэш

4 голосов
/ 19 июня 2009

У меня есть CSV с меткой в ​​первом столбце, за которой следуют значения, разделенные запятыми:

LabelA,45,56,78,90
LabelB,56,65,43,32
LabelC,56,87,98,45

Я бы хотел, чтобы первый столбец (LabelA и т. Д.) Был ключом в хэше с числовыми значениями в массиве.

Я могу прочитать файл в массив или скаляр, но я не уверен, что делать после этого. Предложения ??

Edit: Итак, похоже, что это присваивает значение ключу ... но как насчет чисел с разделителями-запятыми в моем примере? Куда они идут? Они в% хэше? Если так, то не могли бы вы еще больше пояснить свое объяснение? Спасибо.

Ответы [ 5 ]

10 голосов
/ 19 июня 2009

Лично мне нравится модуль Text :: CSV_XS и IO :: File :

use Text::CSV_XS;
use IO::File;

# Usage example:
my $hash_ref = csv_file_hashref('some_file.csv');

foreach my $key (sort keys %{$hash_ref}){
   print qq{$key: };
   print join q{,}, @{$hash_ref->{$key}};
   print qq{\n};
}

# Implementation:
sub csv_file_hashref {
   my ($filename) = @_;

   my $csv_fh = IO::File->new($filename, 'r');
   my $csv = Text::CSV_XS->new ();

   my %output_hash;

   while(my $colref = $csv->getline ($csv_fh))
   {
      $output_hash{shift @{$colref}} = $colref;
   }

   return \%output_hash;
}
7 голосов
/ 19 июня 2009

Хорошо, давайте предположим, что нет специальных символов и т. Д.

Сначала вы откроете файл:

open my $fh, '<', 'some.file.csv' or die "Cannot open: $!";

Затем вы читаете из него в цикле:

while (my $line = <$fh>) {

После этого вы удаляете завершающие белые символы (\ n и другие):

$line =~ s/\s*\z//;

И разбить его на массив:

my @array = split /,/, $line;

Когда он находится в массиве, вы получаете первый элемент массива:

my $key = shift @array;

И сохраните его в хэше:

$hash{$key} = \@array;

(\ @ array означает ссылку на массив).

Весь код:

my %hash;
open my $fh, '<', 'some.file.csv' or die "Cannot open: $!";
while (my $line = <$fh>) {
  $line =~ s/\s*\z//;
  my @array = split /,/, $line;
  my $key = shift @array;
  $hash{$key} = \@array;
}
close $fh;
1 голос
/ 19 июня 2009

См. perlfunc split и perldsc .

  1. Читать каждую строку.
  2. Chomp it.
  3. Разделите его на запятые.
  4. Используйте первое значение в результате в качестве ключа для вашего HoA.
  5. Другие значения становятся массивом.
  6. Сохранить ссылку на массив в хэше под ключом.
  7. ...
  8. Profit !!!

Создать хэш ссылок на массивы :

Ваша структура данных должна выглядеть следующим образом:

my %foo = (
    LabelA => [  2, 3,  56, 78, 90 ],
    LabelB => [ 65, 45, 23, 34, 87 ],
    LabelC => [ 67, 34, 56, 67, 98 ],
);
0 голосов
/ 29 октября 2018

Я думаю, что это также может работать легче.

Переменная $ refhashvariable будет ссылкой на массив хэшей.

Каждый хеш содержит заголовки (в виде хеш-ключа) и значения одной строки CSV. Массив содержит хэши для всех строк в CSV.

use Text::CSV_XS qw( csv );
$refhashvariable = csv(
    in      => "$input_csv_filename",
    sep     => ';',
    headers => "auto"
);    # as array of hash

Это работает для меня. Я не пробовал в случае, если CSV не имеет заголовков.

0 голосов
/ 14 августа 2017

Текст :: CSV :: Hashify

Превратить файл CSV в хеш Perl:

# Simple functional interface
use Text::CSV::Hashify;
$hash_ref = hashify('/path/to/file.csv', 'primary_key');

# Object-oriented interface
use Text::CSV::Hashify;
$obj = Text::CSV::Hashify->new( {
        file        => '/path/to/file.csv',
        format      => 'hoh', # hash of hashes, which is default
        key         => 'id',  # needed except when format is 'aoh'
        max_rows    => 20,    # number of records to read; defaults to all
        ... # other key-value pairs possible for Text::CSV
} );

# all records requested
$hash_ref       = $obj->all;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...