Perl - вставка в массивы с использованием ссылок на переменные по сравнению с использованием переменных - PullRequest
0 голосов
/ 10 октября 2010

Вопрос: Почему я не могу поместить элементы в 2d массив, который находится внутри цикла while, который анализирует набор результатов SQL?

Мне нужна помощь, чтобы понять, почему это происходит. Способ хранения данных в 2d массиве может быть выполнен несколькими способами, но для моих целей мне нужно использовать метод push.

Вот код, который работает:

my @tt = (0,1,2,3);
my @t;
push (@t,\@tt);
print "[0][0]:".$t[0][0]."\n";
print "[0][1]:".$t[0][1]."\n";
print "[0][2]:".$t[0][2]."\n";
print "[0][3]:".$t[0][3]."\n";
@tt = (4,5,6,7);
push (@t,\@tt);
print "[1][0]:".$t[1][0]."\n";
print "[1][1]:".$t[1][1]."\n";
print "[1][2]:".$t[1][2]."\n";
print "[1][3]:".$t[1][3]."\n";

Вывод:

-------------------------
[0][0]:0
[0][1]:1
[0][2]:2
[0][3]:3
[1][0]:4
[1][1]:5
[1][2]:6
[1][3]:7


Вот проблема у меня

Я использую SQL для создания результирующего набора с X количеством столбцов. Чтобы сохранить данные в моем массиве, я решил использовать тот же синтаксис, что и выше:

while (@results=$sth->fetchrow_array())
{
    push(@stu_pool,\@results);
} 

Я проверил SQL и проверил набор результатов, поэтому проблема не связана с этим. Я также вернулся к длинному подходу, который оставляет меня с желаемым конечным результатом. Вместо использования push(@stu_pool,\@results); я использовал этот код внутри цикла:

$stu_pool[$index][0] = $results[0];
$stu_pool[$index][1] = $results[1];
$stu_pool[$index][2] = $results[2];
$stu_pool[$index][3] = $results[3];
$stu_pool[$index][4] = $results[4];
$stu_pool[$index][5] = $results[5];
$stu_pool[$index][6] = $results[6];
$index++;

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

print "[0][0]:".$stu_pool[0][0]."\n";
print "[0][1]:".$stu_pool[0][1]."\n";
print "[0][2]:".$stu_pool[0][2]."\n";
print "[0][3]:".$stu_pool[0][3]."\n";
print "[1][0]:".$stu_pool[1][0]."\n";
print "[1][1]:".$stu_pool[1][1]."\n";
print "[1][2]:".$stu_pool[1][2]."\n";
print "[1][3]:".$stu_pool[1][3]."\n";

Повторить:

Почему метод push не работает внутри цикла while?

Ответы [ 3 ]

9 голосов
/ 11 октября 2010

Позвольте мне немного изменить ваш первый пример.

my @tt = (0,1,2,3);
my @t;
push (@t,\@tt);
@tt = (4,5,6,7);
push (@t,\@tt);
print "[0][0]:".$t[0][0]."\n";
print "[0][1]:".$t[0][1]."\n";
print "[0][2]:".$t[0][2]."\n";
print "[0][3]:".$t[0][3]."\n";
print "[1][0]:".$t[1][0]."\n";
print "[1][1]:".$t[1][1]."\n";
print "[1][2]:".$t[1][2]."\n";
print "[1][3]:".$t[1][3]."\n";

Выход:

[0][0]:4
[0][1]:5
[0][2]:6
[0][3]:7
[1][0]:4
[1][1]:5
[1][2]:6
[1][3]:7

Вы не копируете @tt в @t. Вы помещаете ссылку на переменную @tt в @t. Поэтому, когда что-то еще происходит с @tt, оно меняется и при извлечении через @t. Чтобы действительно сделать копию, вам нужно push(@t,[@tt]) или @{$t[$i]} = @tt, если $i является соответствующей индексной переменной.

Или для другого примера попробуйте push(@stu_pool, [@results]);

5 голосов
/ 10 октября 2010

Есть только один @results - вы делаете каждый элемент @stu_pool ссылкой на один и тот же @results, который (в последний раз, когда проверяется условие цикла) будет в конечном итоге содержать () .

Вам нужно добавить my: while (my @results = $sth->fetchrow_array) { будет работать нормально, потому что теперь каждый раз в цикле @results - это другой массив.

1 голос
/ 11 октября 2010

Зачем вообще цикл? Это гораздо проще сделать:

my $results = $sth->fetchall_arrayref();

или если вы настаиваете на использовании переменной массива:

my @results = @{$sth->fetchall_arrayref()};
...