将 csv 数据转换为特定格式 DYNAMIC

Convert csv data to specific format DYNAMIC

我将此前端 CSS 数据存储在网页中。这是文本文件中的数据。

secid,Initial_shares
002826,3777
0028262,3777
0028262,3777
0028262,3777
0028262,3777
0028262,3777

我需要将此文本文件转换为以下格式。一次,我将其转换为以下格式,我将能够在前端显示它。下面这个格式是用来在jqgrid中显示数据的。

var secid =
            [
             "002826", "0028262", "0028262", "0028262", "0028262", "0028262"];
var Initial_shares =
        [
            "3777", "3777", "3777", "3777", "3777", "3777"1
        ];

为了将文本转换为上述格式,我使用了以下 perl 代码。请注意。这种转换是静态的。即它知道那里有多少列。在这种情况下,将有 2 列。安全和 Initial_shares。所以这是静态代码

my @a=();
my @b=();

my @a1=();
my @b1=();

my @perl_array=();
my @filena = split(/\|/, $filename);

open (TXT, "<$filename") || die "Can't open $filename: $!\n";
while (my $line=<TXT>) {
    chomp($line);
    ($a2, $b2) = split /,/, $line;

    push @a,('"', "$a2", '"', ',');
    push @b,('"', "$b2", '"', ',');
}

splice @a,0,4; # this splice is used to remove the header name.
splice @b,0,4; # i.e. first row data- secid, Initial_shares

push @a1,"var secid=[@a]";
push @b1,"var Initial_shares=[@b]";

push @perl_array, "@a1; @b1";
close TXT;

@perl_array 将与我们开始时期望的数据类型完全相似。我会把这个perl变量传送到前端显示。

在以下情况下我需要帮助。如果不是 2 列,而是 5 列呢?我们如何将同一个csv文件转换成前面提到的格式。它应该是动态的。有人可以解释一下吗。

这里的想法是首先处理 header 行,然后根据你可以创建映射到每个 header 字段的数组散列。下面是一个示例代码来演示。

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

    my %dynamic;
    my @fields = split(/,/,<DATA>);
    chomp(@fields);

    while(<DATA>){
      chomp();
      my @data_fields=split(/,/);
      for (my $i=0; $i<@fields; $i++){
        push(@{$dynamic{$fields[$i]}}, '"' . $data_fields[$i] . '"');
      }
    }

    my @data_array;
    foreach (@fields){
      push(@data_array, "var $_ = [" . join(',',@{$dynamic{$_}}) . "];");
    }

    print join("\n",@data_array), "\n";

    __DATA__
    secid,Initial_shares,columna,someothercolumn
    002826,3777,1,2
    0028262,3777,a,b
    0028262,3777,5,6
    0028262,3777,g,h
    0028262,3777,4,5
    0028262,3777,h,j

我已经打印出最终数组的数据结构以显示其内容。

var secid = ["002826","0028262","0028262","0028262","0028262","0028262"];
var Initial_shares = ["3777","3777","3777","3777","3777","3777"];
var columna = ["1","a","5","g","4","h"];
var someothercolumn = ["2","b","6","h","5","j"];

这将根据您的 csv 输入动态扩展或收缩。

根据我给你的建议,我会这样做:

use strict;
use warnings;

use JSON;
use Text::CSV;

my $filename = '/path/to/file.csv';

my $csv = Text::CSV->new({ binary => 1 }) or die Text::CSV->error_diag;
open(my $fh, '<', $filename) or die $!;

$csv->column_names($csv->getline($fh));
my $data = $csv->getline_hr_all($fh);

close($fh);

for my $column ($csv->column_names) {
    my $json = encode_json([ map { $_->{$column} } @$data ]);
    print "var $column = $json;\n";
}

这可以非常简单地通过将文件读入数组并在输出时重新格式化来完成

此程序需要输入文件的路径作为命令行参数

use strict;
use warnings;

my @data;
while ( <> ) {
    my @row = /[^,\s]+/g;
    push @{ $data[$_] }, $row[$_] for 0 .. $#row;
}

for my $i ( 0 .. $#data ) {
    my $column = $data[$i];
    printf "var %s = [\n", shift @$column;
    printf "    %s\n", join ', ', map qq{"$_"}, @$column;
    print  "];\n";
}

输出

var secid = [
    "002826", "0028262", "0028262", "0028262", "0028262", "0028262"
];
var Initial_shares = [
    "3777", "3777", "3777", "3777", "3777", "3777"
];