在 perl 中转置

发布于 2024-09-10 12:55:09 字数 205 浏览 4 评论 0原文

我已经开始学习 perl 并喜欢尝试新事物。

我在文本处理方面遇到一些问题。 我有一些表格的文本,

0 1 2 3 4 5 6 7 8 9 10

6 7 3 6 9 3 1 5 2 4 6

我想转置该文本。就像,我想将行设置为列,将列设置为行。有没有办法在 Perl 中做到这一点?

谢谢大家。

I have started learning perl and like to try out new things.

I have some problem in text processing.
I have some text of the form,

0 1 2 3 4 5 6 7 8 9 10

6 7 3 6 9 3 1 5 2 4 6

I want to transpose this text. Like, I want to make rows as columns ans columns as rows. Id there a way to do this in perl?

Thank you all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

許願樹丅啲祈禱 2024-09-17 12:55:09

所以这个解决方案使用数组的数组,每个嵌套数组
是一行数据。非常简单,您可以循环遍历每个中的列
行并使用列将它们推到另一个数组数组上
index 作为将值推送到的索引。这有效果
根据您的要求旋转数据。

#!/usr/bin/env perl

my @rows = ();
my @transposed = ();

# This is each row in your table
push(@rows, [qw(0 1 2 3 4 5 6 7 8 9 10)]);
push(@rows, [qw(6 7 3 6 9 3 1 5 2 4 6)]);

for my $row (@rows) {
  for my $column (0 .. $#{$row}) {
    push(@{$transposed[$column]}, $row->[$column]);
  }
}

for my $new_row (@transposed) {
  for my $new_col (@{$new_row}) {
      print $new_col, " ";
  }
  print "\n";
}

这导致:

0 6 
1 7 
2 3 
3 6 
4 9 
5 3 
6 1 
7 5 
8 2 
9 4 
10 6

So this solution uses an array-of-arrays, each nested array
is a row of data. Very simply you loop over the columns in each
row and push them onto another array-of-arrays using the column
index as the index which to push the value onto. This has the effect
of pivoting the data as you requested.

#!/usr/bin/env perl

my @rows = ();
my @transposed = ();

# This is each row in your table
push(@rows, [qw(0 1 2 3 4 5 6 7 8 9 10)]);
push(@rows, [qw(6 7 3 6 9 3 1 5 2 4 6)]);

for my $row (@rows) {
  for my $column (0 .. $#{$row}) {
    push(@{$transposed[$column]}, $row->[$column]);
  }
}

for my $new_row (@transposed) {
  for my $new_col (@{$new_row}) {
      print $new_col, " ";
  }
  print "\n";
}

This results in:

0 6 
1 7 
2 3 
3 6 
4 9 
5 3 
6 1 
7 5 
8 2 
9 4 
10 6
为人所爱 2024-09-17 12:55:09

以下概述了一种转置数据的方法。完成此示例将很有启发性,因为您将需要使用 CPAN,您将了解有用的 List::UtilList::MoreUtils 模块,您将学习复杂数据结构的基础知识(参见perlreftut, perldscperllol),您将可以使用迭代器在 Perl 中。

use strict;
use warnings;
use List::MoreUtils qw(each_arrayref);

my @raw_data = (
    '0 1 2 3 4 5 6 7 8 9 10',
    '6 7 3 6 9 3 1 5 2 4 6',
);

my @rows = ... ; # Look up map() and split() to fill in the rest.
                 # You want an array of arrays.

my @transposed;  # You will build this in the loop below.

my $iter = each_arrayref(@rows);  # See List::MoreUtils documentation.

while ( my @tuple = $iter->() ){
    # Do stuff here to build up @transposed, which
    # will also be an array of arrays.
}

Here's an outline of one way to transpose data. Working through this example will be instructive because you will need to use CPAN, you will learn about the useful List::Util and List::MoreUtils modules, you will learn the basics of complex data structures (see perlreftut, perldsc, and perllol), and you will get to use an iterator in Perl.

use strict;
use warnings;
use List::MoreUtils qw(each_arrayref);

my @raw_data = (
    '0 1 2 3 4 5 6 7 8 9 10',
    '6 7 3 6 9 3 1 5 2 4 6',
);

my @rows = ... ; # Look up map() and split() to fill in the rest.
                 # You want an array of arrays.

my @transposed;  # You will build this in the loop below.

my $iter = each_arrayref(@rows);  # See List::MoreUtils documentation.

while ( my @tuple = $iter->() ){
    # Do stuff here to build up @transposed, which
    # will also be an array of arrays.
}
久光 2024-09-17 12:55:09

当然有,而且迈克指出了最简单的方法。如果您正在学习,您可能想编写自己的函数?
首先,您想要在空格上分割每一行以获得值数组(或推送 单词列表放入数组中,如 道尔顿的回答;在 Perl 中,做任何事情总是有不止一种方法)
然后,对于数组中的每个元素,您想要打印它及其第二个数组中的对应项放在同一行上。 (如果一个数组先于另一个数组耗尽,你会怎么做?)

当然,如果你想学习 Perl,你肯定也想学习使用 CPAN,所以使用 Data::Pivot 仍然值得尝试。

There certainly is, and Mike has pointed out the simplest way. If you are learning, you probably want to write your own function?
First, you want to split each line on spaces to get an array of values (or push the list of words into the array, as in Dalton's answer; in Perl, there's always more than one way to do anything)
Then, for each element in the array, you want to print it and its counterpart in the second array onto the same line. (What will you do if one array runs out before the other?)

Of course, if you want to learn Perl, you will also definitely want to learn to use CPAN as well, so it's still worthwhile to try using Data::Pivot.

时光沙漏 2024-09-17 12:55:09
use strict;
# read the first line
my @labels = split ' ', <>;
# read and ignore the empty second line
<>;
# read the third line
my @values = split ' ', <>;
# transpose (I suppose you'll do more with the table than just printing it)
my %table = map { $labels[$_] => $values[$_] } 0..$#labels;
# print
foreach (@labels) {
    print "$_ $table{$_}\n";
}
use strict;
# read the first line
my @labels = split ' ', <>;
# read and ignore the empty second line
<>;
# read the third line
my @values = split ' ', <>;
# transpose (I suppose you'll do more with the table than just printing it)
my %table = map { $labels[$_] => $values[$_] } 0..$#labels;
# print
foreach (@labels) {
    print "$_ $table{$_}\n";
}
素衣风尘叹 2024-09-17 12:55:09

这是我的新脚本,用于转置制表符分隔的文件。如果您愿意,请将 \t 更改为您的分隔符。

#!/usr/bin/perl -anF/\t|\n/
$n = @F - 1 if !$n;
for $i (0..$n) {
    push @{ $m->[$i] }, $F[$i];
}
END {
    for $r (@$m) {
        print join("\t", @$r), "\n";
    }
}

或者作为 104 个字符的“一行”(添加撇号-反斜杠-换行符-撇号以避免水平滚动):

perl -anF'\t|\n' -e'$n=@F-1if!$n;for(0..$n){push@{$m[$_]},$F[$_]}'\
'END{print map{join"\t",@$_,"\n"}@$m}'

Here's my new script to transpose a tab-delimited file. Change \t to your delimiter if you like.

#!/usr/bin/perl -anF/\t|\n/
$n = @F - 1 if !$n;
for $i (0..$n) {
    push @{ $m->[$i] }, $F[$i];
}
END {
    for $r (@$m) {
        print join("\t", @$r), "\n";
    }
}

or as a 104 character "one liner" (with apostrophe-backslash-newline-apostrophe added to avoid horizontal scrolling):

perl -anF'\t|\n' -e'$n=@F-1if!$n;for(0..$n){push@{$m[$_]},$F[$_]}'\
'END{print map{join"\t",@$_,"\n"}@$m}'
笑梦风尘 2024-09-17 12:55:09
use List::UtilsBy qw/zip_by/;

my @transposition = zip_by { [ @_ ] } @matrix;

https://metacpan.org/pod/List::UtilsBy#zip_by

use List::UtilsBy qw/zip_by/;

my @transposition = zip_by { [ @_ ] } @matrix;

https://metacpan.org/pod/List::UtilsBy#zip_by

内心激荡 2024-09-17 12:55:09

我在寻找一种方法来转置通过读取文件构建的 AoA 时遇到了这个问题,但是当然,这个解决方案仍然适用于任何 AoA,并且它不需要数组引用具有相同数量的元素。我知道这是一个老问题,但由于我仍在学习,如果有一些关于如何改进我的解决方案的批评/示例,那就太棒了。

my $max_rows = 0;
foreach my $line (@copy) {
    my $ref = ();
    push @$ref, split(/\s+/, $line);
    my $rows = scalar(@$ref);
    $aoa[$i] = \@$ref;
    $i++;
    if ($rows > $max_rows) {
        $max_rows = $rows;
    }
}

for (my $i = 0; $i <= $max_rows; $i++) {
    my @aoa_t = ();
    for (my $k = 0; $k <= $#aoa; $k++) {
        if ($aoa[$k]->[$i]) {
            push @aoa_t, $aoa[$k]->[$i];
        } else {
            push @aoa_t, " ";
        }
        print " @aoa_t\n";
    }
    if ($aoa_t[0] eq " ") {
        last;
    } else {
        $t_aoa[$i] = \@aoa_t;
    }
}

它对于包含 200 多行空格分隔格式数据的文件非常有效。如果本论坛适合的话,我们将不胜感激。问候。

I ran across this question while searching for a way to transpose an AoA I built by reading a file, but of course, this solution will still work for any AoA, and it doesn't require the array references have equal numbers of elements. I know this is an old question, but as I'm still learning, it would be awesome to have some critique/examples of how to improve my solution.

my $max_rows = 0;
foreach my $line (@copy) {
    my $ref = ();
    push @$ref, split(/\s+/, $line);
    my $rows = scalar(@$ref);
    $aoa[$i] = \@$ref;
    $i++;
    if ($rows > $max_rows) {
        $max_rows = $rows;
    }
}

for (my $i = 0; $i <= $max_rows; $i++) {
    my @aoa_t = ();
    for (my $k = 0; $k <= $#aoa; $k++) {
        if ($aoa[$k]->[$i]) {
            push @aoa_t, $aoa[$k]->[$i];
        } else {
            push @aoa_t, " ";
        }
        print " @aoa_t\n";
    }
    if ($aoa_t[0] eq " ") {
        last;
    } else {
        $t_aoa[$i] = \@aoa_t;
    }
}

It worked very well for a file with 200+ lines of data in space delimited format. Any feedback is appreciated, if that is appropriate in this forum. Regards.

゛清羽墨安 2024-09-17 12:55:09

Array-Transpose-0.06 怎么样?

http://metacpan.org/pod/Array::Transpose

how about Array-Transpose-0.06 ?

http://metacpan.org/pod/Array::Transpose

蘸点软妹酱 2024-09-17 12:55:09
use strict;
my ($i, $rows, $cols) = (0, 10, 100);
# initiate array 10x100
my $array = [map {[map {$i++} (1..$cols)]} (1..$rows)];
# transpose array into 100x10 array
my $transpose = [map {[map {shift @$_} @$array]} @{$array->[0]}];

数组必须是一个矩阵,即每行的列必须相等,原始数组将被破坏

此代码不会使用额外的内存进行转置,x2对于其他库,对于大型数组例如100x1M,这很重要

use strict;
my ($i, $rows, $cols) = (0, 10, 100);
# initiate array 10x100
my $array = [map {[map {$i++} (1..$cols)]} (1..$rows)];
# transpose array into 100x10 array
my $transpose = [map {[map {shift @$_} @$array]} @{$array->[0]}];

array must be a matrix, i.e columns must be equal for each row, original array will be destroyed

this code will not use extra memory for transpose, x2 for other libraries, for large array for example 100x1M, it matters

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文