2010-05-31 3 views
0

Прямо сейчас я пытаюсь синхронизировать два файла данных, которые перечислены по дате, чтобы впоследствии можно было сравнивать. Однако я не могу напечатать только строки, в которых совпадают даты. На этом этапе я выделил данные для каждого файла на 2 массива. Мне нужно найти только даты, которые находятся в обоих массивах, и распечатать их. Любые предложения будут высоко ценится.Соответствующие элементы из 2 массивов в perl

Вот пример набора исходных данных, что я работаю с, каждый файл находится в том же формате:

 
09/11/2009,00:56:00,51.602,47.894,87,88,0,1032 
09/12/2009,00:56:00,57.794,55.796,93,54,0,1023.6 
09/13/2009,00:56:00,64.292,62.204,93,66,0,1014.4 
09/14/2009,00:56:00,61.592,55.4,80,25,0,1009.6 
09/15/2009,00:56:00,58.604,53.798,84,31,0,1009.1 
09/16/2009,00:56:00,53.6,48.902,84,45,0,1017 

Я расколоть дату в массив для каждого файла. Моя конечная цель - напечатать только строки кода, в которых оба файла имеют данные. Поэтому для этого я хотел сравнить 2 массива с элементами, являющимися датами.

Мой исходный код выглядел следующим образом:

foreach $bdate(@bdate){ 
while (<PL>){ 
    chomp; 
    @arr = split (/,/); 
    $pday=$arr[1]; 
    push @pdate, $pday; 
    if ($bdate eq $pdate){ 
     print "$bdate,$pday\n"; 
    } 
} 
+2

Что вы подразумеваете под "указанными по дате"? Можете ли вы представить пример кода, чтобы показать, насколько вы получили, и какая часть не работает? – Ether

+0

heres и пример моего набора данных. В целях моего вопроса я разделил дату, сохраняя формат mm/dd/yyyy, и ввел ее в массив. Мне нужно взять два из этих массивов и найти только даты, которые находятся в обоих массивах. 02/12/2010,00: 56: 00,27.302,15.602,61,27,3.24193043478261,1001 02/13/2010,00: 56: 00,26.006,6.008,42,75,1.6209652173913,1005.8 02 /14/2010 00:56:00,26.708,16.502,65,329,18.9112608695652,992.9 02/15/2010,00: 56: 00,30,902,19.004,61,287,8.64514782608696,996.8 – Paul

+0

heres образец первого кода, который я пробовал: foreach $ bdate (@bdate) { while () { chomp; \t @arr = split (/, /); \t $ pday = $ arr [1]; \t push @pdate, $ pday; \t \t if ($ bdate eq $ pdate) { \t print "$ bdate, $ pday \ n"; \t \t} \t \t \t } – Paul

ответ

0

Вы против использования внешней функции Unix «комм»?

+0

Я думаю, что OP ищет совпадение в первом столбце каждой строки. comm для этого не очень полезно. – RET

4

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

Затем вы можете распечатать ключи, соответствующие значениям 2 или более;

print $_,"\n" for grep {$dates{$_} > 1} keys %dates; 

(тестировался, написанный на машине, без Perl)

... и быстрый поиск CPAN поворачивает вверх List::Compare, с этим примером;

$lc = List::Compare->new(\@Llist, \@Rlist); 

@intersection = $lc->get_intersection; 
+0

Благодарим за предположение, однако первый метод не смог опустить даты, которые были во втором массиве, а не в первом. И второй метод, который я не мог использовать, потому что этот модуль не установлен на сервере, где мои данные. Это школьный сервер, поэтому я не смог бы его установить. Будут ли другие предложения? – Paul

+0

@Paul, Этот ответ и другие общие подходы к поиску общих элементов в списках (пересечение). По этой причине я подозреваю, что может быть что-то интересное с вашими данными или с тем, как вы их интерпретируете. Можете ли вы изменить свой вопрос, чтобы включить примерные данные и ожидаемые результаты? –

+0

Его очень вероятно, что как я интерпретирую это проблема, я очень новичок и сам участвую в Perl. Я перечислил выше образец необработанных данных, с которыми я работаю. В моем сценарии я поместил только даты в массив для обоих файлов, с которыми я работаю. Первый метод, который вы предложили, хорошо зарекомендовал себя для устранения дат из первого массива, которые не были во втором массиве, однако было несколько дат, которые не были найдены во втором массиве, который был напечатан. Я предполагаю, что мои ожидаемые результаты состоят в том, чтобы распечатать список только дат, общих для обоих массивов. – Paul

1

Вот пример из perlfaq4 (немного упрощен):

my (@intersection, %count); 

for my $element (@array1, @array2) { $count{$element}++ } 

for my $element (keys %count) { 
    push @intersection, $element if $count{$element} > 1;   
} 

Более идиоматичен версия:

my (%union, %isect); 
for my $e (@array1, @array2) { $union{$e}++ && $isect{$e}++ } 

my @intersection = keys %isect; 

Оба метода предполагают, что каждый элемент является уникальным в данном массиве.

+0

Спасибо за предложения, однако первый метод не дал никаких результатов, а второй метод дал результаты, однако они были неправильными. Когда я вручную проверял вывод, он включал несколько дат, которые не были в обоих массивах. Спасибо за ваше время, возможно, возникнут другие предложения? – Paul