Как получить доступ к сложной структуре

 
0
 
Perl
ava
Wardrag | 01.10.2013, 12:33
Имеется структура вида:


my $struct = {country_id => 1, towns => [{town_id => 10, text => 'Austria'}]};


Она описывает структуру стран и городов. В каждой стране свой город/города.
Хочу проверить, существует ли айди с конкретным городом перед тем, как его добавить в эту структуру.
В хэш городов добавляю так (проверил через Dumper - правильно)\:


$struct->{towns}-[1] = {town_id => 11, text = 'Belgium'};


Но совершенно не понимаю, как мне искать город по айди, если его нет, и добавить его в хэш.
В будущем надо будет по аналогии искать по айди страну, и, если её нет, добавлять тоже, но уже в первый хэш(их же два).
Скажите, пожалуйста, как это сделать ?
Очень интересует именно такая структура.
Comments (13)
ava
krypt3r | 01.10.2013, 11:53 #

for (@{$struct->{'towns'}})
{
    if ($town_id == $_->{'town_id'})
    {
        # найдено, что-то сделать
    }
    else
    {
        # не найдено, сделать что-то другое
    }
}

PS. У вас странная структура. Что у вас делают названия стран в элементе towns (города)?
ava
Wardrag | 01.10.2013, 11:54 #
Придумал, как смог : ). А как оптимальнее было бы ?
ava
krypt3r | 01.10.2013, 12:01 #
Ну что-то типа такого

{
    country_id => 1,
    country_name => 'Австрия',
    towns => [
        {town_id => 10, text => 'Вена'},
        {town_id => 11, text => 'Грац'},
        {town_id => 12, text => 'Зальцбург'},
        ...
    ]
};
ava
Wardrag | 01.10.2013, 12:14 #
Хм, не понимаю, - как вообще 
@{$struct->{'towns'}
 может работать ? @{$var} -  ссылка на массив, после чего идет ссылка на хеш towns...
Я бы начал так: 

$struct->{towns}->[0]->{town_id}...
...
Я так понимаю, вы ссылаетесь сразу на 

[{town_id => 10, text => 'Austria'}]
 ?
И ещё: как так работает цикл for, что ему не нужно знать число элементов ? Я думал, что всегда нужно сперва их узнать, а потом вести перебор...

ava
krypt3r | 01.10.2013, 12:31 #
Цитата


И ещё: как так работает цикл for, что ему не нужно знать число элементов ? Я думал, что всегда нужно сперва их узнать, а потом вести перебор...

Все примеры, что я видел, перебирали через foreach


foreach — это синоним for с вытекающей отсюда взаимозаменяемости. Замените в моем коде for на foreach, если вам так более наглядно будет.

foreach my $tmp_town (@{$struct->{'towns'}})
{
    if ($town_id == $tmp_town->{'town_id'})
    ...
}
ava
Wardrag | 01.10.2013, 12:59 #
В инете кучу материалов просмотрел, но так и не разобрался сам, а с Ваши слов и объяснений вроде как понял.
Огромное спасибо ))))).
ava
krypt3r | 01.10.2013, 13:05 #
Да не за что. Пост выше, кстати, немного поредактировал
ava
Wardrag | 01.10.2013, 13:50 #
Хм, возникла проблема - добавить элемент в хэш, причем самый первый struct
Запушить выходит нельзя ничего, кроме массива, дык как же тогда добавить его ?) ( в самом моем первом посте)
Смысл: создать элемент с ещё одним id country_id=2 и т.д.
Пытаюсь добавить целый хэш ( дошло, тупо скопировал его и сменил параметры), а оно выдает ошибку мол ссылка не на массив.
Выходит, так нельзя ?
ava
krypt3r | 01.10.2013, 14:17 #
В $struct вы не можете добавить ключ country_id, ибо он уже существует. Нужно переделывать $struct в массив хэшей типа

{
    country_id => 1,
    country_name => 'Австрия',
    towns => [
        {town_id => 10, text => 'Вена'},
        {town_id => 11, text => 'Грац'},
        {town_id => 12, text => 'Зальцбург'},
        ...
    ]
},
{
    country_id => 2,
    country_name => 'Бельгия',
    towns => [
        {town_id => 110, text => 'Брюссель'},
        {town_id => 111, text => 'Антверпен'},
        {town_id => 112, text => 'Брюгге'},
        ...
    ]
},
...

Если я неправильно понял, покажите код и желаемую структуру данных. 
ava
Wardrag | 01.10.2013, 14:32 #
У меня country_id связан с  массивом хэшей towns
Вот так вот: country_id => towns => [{ тут города страны } ]
Добавил обычным присваиванием в хэш.
Но из-за этого нужно сначала в цикле набивать города, а потом огромный хэш сохранить вмести с городами и новым айди страны, затем меняется айди страны( по возрастанию или с переменной), опять прогоняются города, разумеется, все разные.
Вот что я хочу сделать...
ava
Wardrag | 01.10.2013, 20:22 #
Написал на email : ). Проверьте, пожалуйста!
ava
infarch | 02.10.2013, 10:03 #
А вы уверены что не хотите пользоваться базами данных вместо всех эти мегахешей? SQLite поможет отцу русской демократии )
ava
Alex Feat | 02.10.2013, 11:21 #
Не знаю, правильно ли я понял задачу, но почему не сделать структуру в которой проще будет искать? Т.е. мы делаем не массив хешей, а просто хеш.


country_id => {
    name => 'country name',
    towns => {
        town_id => {
            name => 'town name',
        }
    }
}


таким образом, мы можешь легко и просто доставать нам нужную информацию.


my $struct = {
    1 => {
        towns => {
            10 => { text => 'Austria'},
        }
    }
};

if ( $struct->{$country_id}->{towns}->{$town_id} ) {
    # такой город есть
    print $struct->{$country_id}->{towns}->{$town_id}->{text}, "\n"; # вывели текст
} else {
    # город не найден
    $struct->{$country_id}->{towns}->{$town_id} = { text => 'new town' }; # добавили город
}




Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit