Perl: назначение ссылок на элементы массива в цикле Foreach - PullRequest
5 голосов
/ 13 мая 2011

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

Я пытаюсь загрузить 9 текстовых файлов, каждый из которых состоит из матрицы из 7 строкиз 7 символов, разделенных пробелами, а затем сохранить каждую ссылочную матрицу в элемент в массиве.Я читаю в каждом файле просто отлично, но когда я обращаюсь к своему массиву, все элементы одинаковы.Я искал решение, и либо на мой вопрос нигде не ответили, либо (что более вероятно) я не понимаю ответа.Вот проблемный раздел моего кода:

my @boardarray = (1, 2, 3, 4, 5, 6, 7, 8, 9);
sub LoadBoards {
    my (@board, $infile, @allboards);
    my $i = 1;
    @allboards = @boardarray;
    foreach (@allboards) {
        my $infile = "board" . $i . "\.brd";
        open FILE, "< $infile" or die $!;
        my $line = 0;
        while (<FILE>) {
            chomp $_;
            my @chars = split (/ /,$_);
            $board[$line] = [@chars];
            $line++;
        }
    my $tempboard = \@board;
        DisplayOneBoard($tempboard); print ("\n");              #Test A
    $boardarray[$i-1] = \@board;                                #Problem line?
        DisplayOneBoard($boardarray[$i-1]); print ("\n");       #Test B
        DisplayOneBoard($boardarray[0]); print ("\n----\n");    #Test C
    $i++;
    }
}

-Я попытался присвоить переменные как элементы @boardarray без изменений.
-Я использовал @boardarray в цикле foreach и изменил егок скопированным @allboards без улучшений.
Я ожидаю, что строки 'Test A' и 'Test B' будут одинаковыми, а строка 'Test C' останется первой загруженной матрицей. Однако все триодинаковы для каждой итерации.
(для итерации 1 они все являются матрицей 1. Для итерации 2 они все являются матрицей 2 и т. д.)
В конце все элементы представляют собой одну и ту же матрицу (матрица 9).

Любая помощь будет принята с благодарностью.Спасибо.

Ответы [ 2 ]

8 голосов
/ 13 мая 2011

Проблема в том, что вы повторно используете один и тот же @board каждый раз через цикл.Когда вы помещаете ссылку на эту доску на @boardarray, вы каждый раз нажимаете ссылку, указывающую один и тот же @board.Исправить это просто, просто переместите my @board внутрь цикла foreach;это создает новый @board каждый раз.

4 голосов
/ 13 мая 2011

Возможно, вам повезет больше, если немного разбить код и использовать массивы в качестве стеков с помощью push / pop:

sub load_file {
    my ($filename) = @_;
    open my $file, '<', $filename or die $!;
    my @array;
    while (<$file>) {
        chomp $_;
        my @chars = split (/ /,$_);
        push @array, \@chars;    ### adds a reference to the char line 
                                 ### array to the end of the array
    }
    return \@array;              ### return a ref to the 2-d array
}

sub load_files {
    my ($num) = @_;
    my %boards;     ### A hash, so we can refer to loaded arrays
                    ### with a string ID

    for my $filenum ( 1 .. $num ) {
         my $filename = "board" . $filenum . "\.brd";
         $boards{$filenum} = load_file($filename);
    }

    return \%boards;   ### return a ref to the hash of 2-d arrayrefs
}

### use it now...
my $boards = load_files(9); ### load 9 files.

DisplayOneBoard($boards->{6}); ### dereference our hashref, pass board in
                               ### key '6'to be displayed
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...