Как ссылаться на данные в массиве/хэше из ответа JSON в Perl

Я пишу код Perl, и я совершенно нуб (специализируюсь на PHP и JS). Я получаю некоторые данные из запроса API JSON, и я хочу сослаться на данные и создать некоторые параметры HTML для поля выбора. Но я просто не могу понять, как ссылаться на значения из ответа JSON.

#!/bin/false

use strict;
use warnings;

use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;

use vars qw(@parameters $new $mode $metainfo);

use Data::Dumper qw(Dumper);

sub main
{
    if ($mode ne 'EDIT') {
        return;
    }

    my @pagetypes = _getPagetypes();
    if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
        return "";
    }

    my $html = "";

    foreach (@pagetypes) {
        my $pagetype = $_;

        return Dumper @pagetypes;

        $html .= sprintf(
            '<option value = "%s">%s</option>',
            $pagetype->{"identifier"},
            encode_utf8($pagetype->{"label"}),
        );
    }

    return $html;
}

##
# Get Pagetypes from API
##
sub _getPagetypes
{
    my $url = sprintf(
        "%s/page-types/",
        $ENV{'URL'}
    );

    my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
    my $header = HTTP::Request->new(GET => $url);
    my $request = HTTP::Request->new('GET', $url, $header);
    my $response = $ua->request($request);

    my @data = decode_json($response->content);
    my @pagetypes = @data[0]->{'pageTypes'};

    return @pagetypes;
}

Там, где написано return Dumper $pagetypes;, записывается следующий вывод:

$VAR1 = [
    {
        'label' => 'Projektsteckbrief',
        'identifier' => 'pagetype-profile'
    }
];

Я пробовал $pagetype->{"label"} и $pagetypes[0]->{"label"} и многое другое... но я просто не знаю, как получить там метку и идентификатор.

Обновить:

Я попытался реализовать типы страниц вручную, и это отлично работает с методом main() (без вызова дампера):

sub _getPagetypes
{
    my @pagetypes = (
        {
            identifier => "pagetype-profile",
            label => "Projektsteckbrief",
        },
    );

    return @pagetypes;
}

ОБНОВЛЕНИЕ 2:

Итак, у меня возникла новая проблема... она еще не работает полностью, но ответ Bl00D4NGEL в любом случае очень помог!

Итак, мой код сейчас выглядит так:

#!/bin/false

use strict;
use warnings;

use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use Project::Util::Api;

use vars qw(@parameters $new $mode $metainfo);

sub main
{
    if ($mode ne 'EDIT') {
        return;
    }

    my @pagetypes = _getPagetypes();
    if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
        return "";
    }

    my $html = "";

    foreach my $pagetype (@pagetypes) {
        # selection will be automatically set by Imperia
        $html .= sprintf(
            '<option value = "%s">%s</option>',
            $pagetype->[0]->{"identifier"},
            encode_utf8($pagetype->[0]->{"label"}),
        );
    }

    return $html;
}

##
# Get Pagetypes from API
##
sub _getPagetypes
{
    my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
    my @pagetypes = $response->{"pageTypes"};

    return @pagetypes;
}

$new = main();

Проблема в том, что теперь отображается только один элемент. Итак, $pagetype в моем цикле foreach выглядит так, как будто это все еще массив со всеми элементами внутри, а затем $pagetype->[0] дает мне только первый элемент из массива.

Когда я использую for вместо foreach вот так:

for ( $a = 0 ; $a <= 10 ; $a++ ) {
    $html .= sprintf(
        '<option value = "%s">%s</option>',
        @pagetypes[0]->[$a]->{"id"},
        encode_utf8(@pagetypes[0]->[$a]->{"label"}),
    );
}

Я получаю 10 элементов из 200, но никак не могу понять, как получить длину массива @pagetypes. Я пробовал следующее:

# 500 Server error (because of long loading?)
for ( $a = 0 ; $a <= @pagetypes[0] ; $a++ ) {

my $pagetypesLength = @pagetypes;
# Only 2 items are displayed
for ( $a = 0 ; $a <= @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= $pagetypesLength ; $a++ ) {
for ( $a = 0 ; $a <= scalar @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= length @pagetypes ; $a++ ) {

ОБНОВЛЕНИЕ 3 (НАКОНЕЦ-ТО РАБОТАЕТ):

Итак, наконец, мне удалось заставить его работать. Окончательный код следующий:

#!/bin/false

use strict;
use warnings;

use Encode;
use Project::Util::Api;

use vars qw(@parameters $new $mode $metainfo);

sub main
{
    if ($mode ne 'EDIT') {
        return;
    }

    my $items = _getData();
    if (0 == scalar @$items) {
        return "";
    }

    my $html = "";

    # $#{$items} is last index of array reference $items
    for (my $i = 0 ; $i <= $#{$items} ; $i++) {
        if (defined $items->[$i]->{"id"}) {
            # option selection will be automatically set by Imperia
            $html .= sprintf(
                '<option value = "%s">%s</option>',
                $items->[$i]->{"identifier"},
                encode_utf8($items->[$i]->{"label"}),
            );
        }
    }

    return $html;
}

##
# Get Pagetypes from API
##
sub _getData
{
    my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");

    return $response->{"pageTypes"};
}

$new = main();

В вашем вопросе обсуждается return Dumper $pagetypes;, но код не показывает скалярную переменную $pagetypes, он показывает массив @pagetypes. Поэтому мы можем только догадываться, что вы на самом деле делаете, чтобы получить дамп, который вы показали. Пожалуйста, опубликуйте фактический фрагмент кода, который создает дамп, который вы видите.

DavidO 27.05.2019 17:31

Ты прав, извини. Я попытался получить доступ к переменной с помощью $ и не отменил ее. Я обновил фрагмент кода и добавил другую информацию.

user3356082 28.05.2019 09:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
390
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, что переменная $pagetype на самом деле является ссылкой на массив (по крайней мере, глядя на Dumper, это выглядит так) Итак, что, вероятно, должно решить эту проблему, так это:

    my $pagetype = $_;

    $html .= sprintf(

    '<option value = "%s">%s</option>',
    $pagetype->[0]->{"identifier"},
    encode_utf8($pagetype->{"label"}),

    );

Слава богу, это работает! Я думаю, что вы обращаетесь к этому массиву с помощью $pagetype[0]. Я предполагаю, что -> нужно использовать, потому что это ссылка?

user3356082 28.05.2019 09:50

Да, конечно. Вы должны проверить эту статью о Perl Maven: perlmaven.com/array-references-in-perl

Bl00D4NGEL 28.05.2019 16:52

большое спасибо! Могу я попросить вас проверить ОБНОВЛЕНИЕ 2 в моем первоначальном вопросе? С вашим комментарием я получаю только первый элемент массива. Большое спасибо!

user3356082 14.06.2019 18:34

Похоже, вы неправильно обращаетесь к @pagetypes. если вы хотите получить доступ к массиву или хеш-элементу, вам нужно ввести $variable[0] или $variable{'key'} для доступа к нему. Вы пытались получить доступ к переменной, используя @pagetypes[0]->[$a]->{"id"}, что неверно, поэтому возникла синтаксическая ошибка.

Bl00D4NGEL 14.06.2019 19:18

нет, @pagetypes[0]->[$a]->{"id"} работает нормально. Проблема в том, что я не знаю, как получить правильный код для длины массива в цикле for. и с foreach единственный $pagetype всегда является полным массивом @pagetypes в дампере :(

user3356082 17.06.2019 10:05

чтобы получить длину массива в perl, используйте scalar(@array), но если я правильно понимаю ваш сценарий, массив @pagetype имеет только один элемент (в индексе 0), и там есть несколько значений, я прав с этим ? Если это так, вам может понадобиться сделать что-то вроде my @values = @{$pagetypes[0]}, а затем выполнить for my $value (@values) { ... } для перебора элементов.

Bl00D4NGEL 17.06.2019 12:03

Другие вопросы по теме