2012-02-29 3 views
0

Я застрял на эту проблему в течение нескольких дней и не знаю, какие структуры данных следует использовать в PerlСохранение дублирующих входов в отличие в Perl

Предположим, что у меня есть этот файл со следующими входами:

lookup hello 
lookup good night 
good night 

Я хочу, чтобы иметь возможность хранить «поиск», связанный с «привет», «поиск», связанный с «спокойной ночью» и, наконец, «спокойной ночи», связанной ни с чем другим. Должен ли я использовать хэш или массив? Если я установлю «поиск» в качестве ключа хеша, я потеряю «привет» информацию. Если я установил «спокойную ночь» в качестве ключа, я в конечном итоге потеряю 3-ю строку информации.

Что мне делать?

EDIT: Есть определенные ключевые слова (которые я назвал «lookup»), у которых есть вещи, которые связаны с ними. Например, за «паролем» будет следовать фактический пароль, тогда как «login» не должен иметь ничего за ним.

+4

Почему первое слово из первых двух строк быть связаны с остальной частью этих линий, но первые два * * слова третьей линии будут связаны ни с чем? –

+2

+1 комментарий @ AdamMihalcin. Если я не могу понять шаблон в моей голове, я, конечно, не могу написать для него код. –

+0

, потому что есть определенные ключевые слова (которые я назвал «lookup»), у которых есть вещи, которые связаны с ними. Например, за «паролем» будет следовать фактический пароль, тогда как «login» не должен иметь ничего за ним. – Sakura

ответ

1

Непонятно, как вы ожидаете разбить слова здесь, но в общем случае, если вам нужно делать случайный поиск (произвольным словом), хэш лучше подходит, чем массив. Без дополнительной информации о том, что вы пытаетесь сделать здесь, трудно быть более конкретным.

1

Похоже, вы хотите хэш массивов. Не обращая внимания на вопрос о том, как решить ключ является «спокойной ночи» вместо «хорошо» (и только при условии, ключ должен быть «хорошо»), вы могли бы сделать что-то вроде:

 
#!/usr/bin/env perl 

use strict; 
use warnings; 

my %hoa; # hash of arrays 
while(<>) { 
    my @f = split; 
    my $k = shift @f; 
    $hoa{ $k } = [] unless $hoa{ $k }; 
    push @{$hoa{ $k }}, join(' ', @f); 
} 

foreach my $k(keys(%hoa)) { 
    print "$k: $_\n" foreach (@{$hoa{ $k }}); 
} 
+3

'$ hoa {$ k} = [], если $ hoa {$ k};' не нужно. [Autovivification] (http://perldoc.perl.org/perlref.html) создает массив для вас, когда вы 'push @ $ ref, $ value' и' $ ref' являются 'undef'. – cjm

+0

Обратите внимание, что это не хэш массивов, а хэш массива refs. Кроме того, хотя автовивитация удобна и часто считается идиоматическим perl, как точка личного стиля, я предпочитаю быть явным. Я не знаю никаких технических причин, чтобы избежать явной инициализации массива ref. Если есть причина, прокомментируйте, чтобы просветить меня! –

0

Не совсем уверен, что ты хотят, но это нормально:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dump qw(dump); 

# build a hash of keywords 
my %kword = map{ $_ => 1}qw(lookup kword1 kword2); 
my %result; 
while(<DATA>) { 
    chomp; 
    my ($k, $v) = split(/ /,$_, 2); 
    push @{$result{$k}}, $v if exists $kword{$k}; 
} 
dump%result; 

__DATA__ 
lookup hello 
lookup good night 
good night 
kword1 foo 
kword1 bar 

выход:

("kword1", ["foo", "bar"], "lookup", ["hello", "good night"]) 
0

вы также можете использовать хэш хэшей, если вы собираетесь хранить другую часть данных с вашей связаны «смотреть вверх "->" спокойной ночи ", с которой будет легко получить доступ позже. например:

%result = (
    'lookup' => { 
     'hello' => $storage1, 
     'good night' => $storage2, 
    }, 
    'good night' => { 
    } 
); 
Смежные вопросы