Perl의 배열에서 해시를 얻는 방법은 무엇입니까?
-
09-06-2019 - |
문제
Perl로 작은 "DBQuery" 함수를 작성하여 SQL 문을 보내고 다시 받는 단일 라이너와 해시 배열을 가질 수 있습니다.레코드세트.그러나 Perl 구문(및 아마도 이상한 포인터/참조 문제)에 문제가 발생하여 데이터베이스에서 가져오는 해시의 정보를 압축할 수 없습니다.아래 샘플 코드는 문제를 보여줍니다.
다음 구문을 사용하면 배열 내부의 해시에서 "Jim" 데이터를 가져올 수 있습니다.
print $records[$index]{'firstName'}
"짐"을 반환합니다.
하지만 배열의 해시 레코드를 자체 해시 변수에 먼저 복사하면 이상하게도 해당 해시에 있는 데이터에 더 이상 액세스할 수 없습니다.
%row = $records[$index];
$row{'firstName'};
""(공백)을 반환합니다.
다음은 문제를 보여주는 전체 샘플 코드입니다.도움을 주시면 감사하겠습니다.
my @records = (
{'id' => 1, 'firstName' => 'Jim'},
{'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();
$numberOfRecords = scalar(@records);
print "number of records: " . $numberOfRecords . "\n";
for(my $index=0; $index < $numberOfRecords; $index++) {
#works
print 'you can print the records like this: ' . $records[$index]{'firstName'} . "\n";
#does NOT work
%row = $records[$index];
print 'but not like this: ' . $row{'firstName'} . "\n";
}
해결책
중첩된 데이터 구조에 해시가 포함되어 있습니다. 참조, 해시가 아닙니다.
# Will work (the -> dereferences the reference)
$row = $records[$index];
print "This will work: ", $row->{firstName}, "\n";
# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print "This will work: ", $row{firstName}, "\n";
깊은 Perl 데이터 구조를 본 적이 있다면 다음을 사용하여 인쇄하면 도움이 될 수 있습니다. 데이터::덤퍼 사람이 읽을 수 있는(그리고 Perl이 구문 분석할 수 있는) 형식으로 인쇄합니다.
다른 팁
해시 배열은 실제로 해시를 포함하지 않지만 오히려 참고자료 해시로.이 줄은:
%row = $records[$index];
하나의 항목으로 %row를 할당합니다.핵심은 스칼라:
{'id' => 1, 'firstName' => 'Jim'},
이는 해시에 대한 참조이며 값은 비어 있습니다.
당신이 정말로 하고 싶은 것은 이것이다:
$row = $records[$index];
$row->{'firstName'};
그렇지 않으면:
$row = %{$records[$index];}
$row{'firstName'};
다른 사람들은 해시와 해시 참조에 대해 논평했습니다.언급해야 할 또 다른 사항은 DBQuery 기능입니다. DBI에 이미 내장된 작업을 수행하려는 것 같습니까?귀하의 질문을 올바르게 이해한다면 다음과 같은 것을 복제하려고하는 것입니다. selectall_arrayref:
이 유틸리티 메소드는 "prepare", "execute" 및 "fetchall_arrayref"를 단일 호출로 결합합니다.가져온 데이터의 각 행에 대한 배열(또는 해시, 아래 참조)에 대한 참조를 포함하는 배열에 대한 참조를 반환합니다.
위의 멋진 답변에 추가하기 위해 항상, 항상, 항상(예, 세 개의 "항상") 코드 상단에 "경고 사용"을 사용해야 한다는 점을 추가하겠습니다.그렇게 했다면 "-e 라인 1에서 짝수 크기의 목록이 예상되는 참조를 찾았습니다."라는 경고를 받았을 것입니다.
실제로 배열에 있는 것은 해시가 아니라 해시 참조입니다.이 개념을 이해하지 못한다면 읽어볼 가치가 있을 것입니다. 펄레프 선적 서류 비치.
당신이해야 할 해시를 얻으려면
my %hash = %{@records[$index]};
예.
my @records = (
{'id' => 1, 'firstName' => 'Jim'},
{'id' => 2, 'firstName' => 'Joe'}
);
my %hash = %{$records[1]};
print $hash{id}."\n";
하지만.학문적 목적이 아니라면 왜 이런 일을 하고 싶어하는지 잘 모르겠습니다.그렇지 않으면 DBI 모듈에서 fetchall_hashref/fetchall_arrayref를 사용하거나 Class::DBI와 같은 것을 사용하는 것이 좋습니다.
또한 사용하기 좋은 Perl 관용구는 다음과 같습니다.
for my $rowHR ( @records ) { my %row = %$rowHR; #or whatever... }
목록을 반복합니다.