Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как получить доступ к сложной структуре 
:(
    Опции темы
Wardrag
  Дата 1.10.2013, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



Имеется структура вида: 

Код

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


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

Код

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


Но совершенно не понимаю, как мне искать город по айди, если его нет, и добавить его в хэш.
В будущем надо будет по аналогии искать по айди страну, и, если её нет, добавлять тоже, но уже в первый хэш(их же два).
Скажите, пожалуйста, как это сделать ?
Очень интересует именно такая структура.

Это сообщение отредактировал(а) Wardrag - 1.10.2013, 11:34
PM MAIL   Вверх
krypt3r
Дата 1.10.2013, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Код

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

PS. У вас странная структура. Что у вас делают названия стран в элементе towns (города)?
PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



Придумал, как смог : ). А как оптимальнее было бы ?
PM MAIL   Вверх
krypt3r
Дата 1.10.2013, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Ну что-то типа такого
Код

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

PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



Хм, не понимаю, - как вообще 
Код
@{$struct->{'towns'}
 может работать ? @{$var} -  ссылка на массив, после чего идет ссылка на хеш towns...
Я бы начал так: 
Код

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

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


Добавлено через 6 минут и 36 секунд
Кажется, начинаю понимать:

@{$arr} - ссылка на массив
%{arr} - ссылка на хэш

Они нужны, чтобы удобно делать перебор

Это сообщение отредактировал(а) Wardrag - 1.10.2013, 12:16
PM MAIL   Вверх
krypt3r
Дата 1.10.2013, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Цитата

@{$var} -  ссылка на массив, после чего идет ссылка на хеш towns

Не так. Это операция разыменования ссылки на массив
Цитата

@{$struct->{'towns'}}

for/foreach-у нужен массив, а не ссылка на него. Тут явно происходит разыменование массива, лежащем в towns. Каждый элемент массива — это хэш типа {town_id => 10, text => 'Austria'}.
Цитата

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

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

foreach my $tmp_town (@{$struct->{'towns'}})
{
    if ($town_id == $tmp_town->{'town_id'})
    ...
}

Или так можно написать
Код

my @arr = @{$struct->{'towns'}};
my $count = count @arr;
my $i;
for ($i = 0; $i < $count; $i++) {...}

Или вот так
Код

for my $i (0 .. $count - 1) { ... }

Выбирайте вариант, короче, более читабельный для вас.
PS. Если у вас цель — разобраться со сложными структурами данных в перле (хэш хэшей, массив хэшей, хэш массивов и т.д.), то посоветую почитать, например, "Perl. Специальный справочник" Стивена Холзнера. Там в главе "Структуры данных" они рассмотрены

Это сообщение отредактировал(а) krypt3r - 1.10.2013, 13:04
PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



В инете кучу материалов просмотрел, но так и не разобрался сам, а с Ваши слов и объяснений вроде как понял.
Огромное спасибо ))))).
PM MAIL   Вверх
krypt3r
Дата 1.10.2013, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Да не за что. Пост выше, кстати, немного поредактировал
PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



Хм, возникла проблема - добавить элемент в хэш, причем самый первый struct
Запушить выходит нельзя ничего, кроме массива, дык как же тогда добавить его ?) ( в самом моем первом посте)
Смысл: создать элемент с ещё одним id country_id=2 и т.д.
Пытаюсь добавить целый хэш ( дошло, тупо скопировал его и сменил параметры), а оно выдает ошибку мол ссылка не на массив.
Выходит, так нельзя ?
PM MAIL   Вверх
krypt3r
Дата 1.10.2013, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



В $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 => 'Брюгге'},
        ...
    ]
},
...

Если я неправильно понял, покажите код и желаемую структуру данных. 
PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



У меня country_id связан с  массивом хэшей towns
Вот так вот: country_id => towns => [{ тут города страны } ]  (так получилось после добавления нового country_id)
Добавил обычным присваиванием в хэш.
Но из-за этого нужно сначала в цикле набивать города, а потом огромный хэш сохранить вмести с городами и новым айди страны, затем меняется айди страны( по возрастанию или с переменной), опять прогоняются города, разумеется, все разные.
Вот что я хочу сделать...

Это сообщение отредактировал(а) Wardrag - 1.10.2013, 14:33
PM MAIL   Вверх
Wardrag
Дата 1.10.2013, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 19.10.2011

Репутация: нет
Всего: нет



Написал на email : ). Проверьте, пожалуйста!

Это сообщение отредактировал(а) Wardrag - 1.10.2013, 20:23
PM MAIL   Вверх
infarch
Дата 2.10.2013, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



А вы уверены что не хотите пользоваться базами данных вместо всех эти мегахешей? SQLite поможет отцу русской демократии )
PM MAIL   Вверх
Grost
Дата 2.10.2013, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 26.8.2010
Где: Москва

Репутация: нет
Всего: нет



Не знаю, правильно ли я понял задачу, но почему не сделать структуру в которой проще будет искать? Т.е. мы делаем не массив хешей, а просто хеш.

Код

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' }; # добавили город
}





PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0894 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.