Транспонировать в Perl - PullRequest
14 голосов
/ 14 июля 2010

Я начал изучать Perl и хотел бы попробовать что-то новое.

У меня есть некоторые проблемы при обработке текста.У меня есть некоторый текст формы,

0 1 2 3 4 5 6 7 8 9 10

6 7 3 6 9 3 1 5 2 4 6

Я хочу транспонировать этот текст.Например, я хочу сделать строки в виде столбцов, а столбцы - в виде строк.Есть ли способ сделать это в Perl?

Спасибо всем.

Ответы [ 8 ]

13 голосов
/ 14 июля 2010

Так что в этом решении используется массив массивов, каждый вложенный массив представляет собой строку данных.Очень просто вы перебираете столбцы в каждой строке и помещаете их в другой массив массивов, используя индекс столбца в качестве индекса, в который нужно поместить значение.Это приводит к повороту данных по вашему запросу.

#!/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
5 голосов
/ 14 июля 2010

Вот схема одного из способов переноса данных. Работа с этим примером будет поучительной, потому что вам нужно будет использовать CPAN , вы узнаете о полезных модулях List::Util и List::MoreUtils. изучите основы сложных структур данных (см. perlreftut , perldsc и perllol ), и вы получите возможность использовать итератор в 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.
}
3 голосов
/ 14 июля 2010

Конечно, есть, и Майк указал самый простой способ.Если вы изучаете, вы, вероятно, хотите написать свою собственную функцию?
Во-первых, вы хотите разбить каждую строку на пробелы, чтобы получить массив значений (или push the список слов в массив, как в ответ Далтона ; в Perl всегда есть несколько способов что-либо сделать)
Тогда для каждого элемента в массиве, вы хотите напечатать его и его аналог во втором массиве на той же строке.(Что вы будете делать, если один массив закончится раньше другого?)

Конечно, если вы хотите изучать Perl, вы также определенно захотите научиться использовать CPAN, так что все же стоит попробоватьиспользуя Data :: Pivot.

2 голосов
/ 15 декабря 2011

Вот мой новый скрипт для транспонирования файла с разделителями табуляции.Замените \ 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-символьный «один вкладыш» (с добавленным apostrophe-backslash-newline-apostrophe, чтобы избежать горизонтальной прокрутки):

perl -anF'\t|\n' -e'$n=@F-1if!$n;for(0..$n){push@{$$m[$_]},$F[$_]}'\
'END{print map{join"\t",@$_,"\n"}@$m}'
2 голосов
/ 15 июля 2010
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";
}
1 голос
/ 22 октября 2015
use List::UtilsBy qw/zip_by/;

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

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

0 голосов
/ 26 августа 2016
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, имеет значение

0 голосов
/ 19 марта 2014

Как насчет Array-Transpose-0.06?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...