2013-07-23 4 views
1

У меня есть массив (@myarray) со строками, такие как:Разделение определенных строк в массиве?

rs30000489 
rs903484 
rs24567;rs324987;rs234985 
rs5905002 
rs32456;rs2349085 

Когда я соответствовать другому подобному (@otherarray) массив без строк с запятой и несколько rsIDs, с помощью следующего кода:

for $1(0 .. $#otherarray) { 
    for $m(1 .. $#myarray) { 
     if ($myarray[$m] =~ /$otherarray[$i]/i) { 
      $IDmatch = 1; 
     } 
    } 
} 

Сценарий не соответствует ни одному из идентификаторов в строках с точкой с запятой. Я пытался расколоть строки точкой с запятой, как, например:

foreach $string (@myarray) { 
    if ($string =~ m/;/) { 
     push (@newarray, $string); 
    } 
} 

который возвращает массив @new:

rs24567;rs324987;rs234985 
rs32456;rs2349085 

Что я тогда попытаться разбить его на общий характер, как, например:

foreach $line (@new) { 
    $line =~ tr/;//d; 
    $line =~ s/rs/ rs/g; 
    $line = split (/ /); 
} 

Но когда я печатаю массив @new, он просто возвращает нули. Я знаю, что это должно иметь какое-то отношение к моей петле, потому что мне трудно работать с циклами в perl. Пожалуйста, дайте мне знать, если у вас есть идеи! Благодаря!

+1

Это звучит как [XY-проблема] (http://meta.stackexchange.com/q/66377/162416). Что вы действительно хотите делать? Сопоставьте два списка идентификаторов друг против друга? – TLP

+0

Кроме того, вы должны быть более осторожны при написании важных описаний. Что это значит: «без строк с точкой с запятой и несколькими rsID». Без строк с полуколонами звучит как его только полуколоны. Вы должны почти всегда показывать, а не описывать. – TLP

+0

и ваш '' split'' на самом деле не раскол. Его соответствие для ';', а затем нажатие на '@ new' –

ответ

0

Просто несколько вещей о петлях в Perl. Вы написали цикл for двумя разными способами.

for $1(0 .. $#otherarray) { ... } 

и

foreach $line (@new) { ... } 

Вы можете написать первый цикл цикла точно такие же, как 2-й.

foreach $1 (0..$#otherarray) { .. } 

или намного лучше

foreach my $other_array_content (@otherarray) { .. } 

$1 вы использовали это специальный символ (используется в регулярных выражениях).

Затем вы можете использовать split внутри петли foreach.

foreach my $data (@data) { 
    foreach (split /;/,$data) { 

    } 
} 

Вот краткое решение в двух словах вашей проблемы:

my @checked = qw(rs30000489 
    rs9033484 
    rs2349285 
    rs5905402 
    rs32456 
); 

my $idMatch = 0; 
my @data = <DATA>; 

foreach my $data (@data) { 
    foreach my $checked (@checked) { 
    if ($data =~ m/;/) { 
     foreach my $data2 (split /;/, $data) { 
     if ($checked eq $data2) { 
      $idMatch = 1; 
     } 
     } 
    } else { 
     if ($data eq $checked) { 
     $idMatch = 1; 
     } 
    } 
    } 
} 

print $idMatch; 

__DATA__ 

rs30000489 
rs903484 
rs24567;rs324987;rs234985 
rs5905002 
rs32456;rs2349085 
2

Вы не говорите, что вы хотите сделать с этими двумя массивами, но если я правильно понял ваш вопрос peoperly это звучит например, вы, вероятно, захотите найти все те rsID, которые появляются в обоих списках.

Эта программа работает путем преобразования первого массива (пожалуйста использовать лучшие имена, чем myarray и otherarray) в хэш, который имеет все идентификаторы в качестве ключей. Затем он использует grep, чтобы найти все те, что находятся во втором массиве, которые появляются в хэше, нажимая их на массив @dups.

use strict; 
use warnings; 

my @myarray = qw(
    rs30000489 
    rs903484 
    rs24567;rs324987;rs234985 
    rs5905002 
    rs32456;rs2349085 
); 

my @otherarray = qw(
    rs3249487 
    rs30000489 
    rs325987 
    rs324987 
    rs234967 
    rs32456 
    rs234567 
); 

my %rsids = map { $_ => 1 } map { split /;/ } @myarray; 

my @dups = grep $rsids{$_}, @otherarray; 

print "$_\n" for @dups; 

выход

rs30000489 
rs324987 
rs32456 
0

Если вы ищете уникальные вещи, то первое, что вы должны думать о том, хэши. Попытка:

#!/usr/bin/env perl 

use strict; 
use warnings; 

# -------------------------------------- 

use charnames qw(:full :short ); 
use English qw(-no_match_vars); # Avoids regex performance penalty 

use Data::Dumper; 

# Make Data::Dumper pretty 
$Data::Dumper::Sortkeys = 1; 
$Data::Dumper::Indent = 1; 

# Set maximum depth for Data::Dumper, zero means unlimited 
local $Data::Dumper::Maxdepth = 0; 

# conditional compile DEBUGging statements 
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html 
use constant DEBUG => $ENV{DEBUG}; 

# -------------------------------------- 
#  Name: unique 
#  Usage: %hash = unique(@array); 
# Purpose: Create a hash of unique keys from array items. 
# Parameters: @array -- May have multiple entries separated by a semi-colon 
# Returns: %hash -- Unique keys of array items 
# 
sub unique { 
    my @array = @_; 
    my %hash =(); 

    for my $item (@array){ 
    my @items = split m{ \; }msx, $item; 
    $hash{$_} ++ for @items; 
    } 

    return %hash; 
} 

# -------------------------------------- 

my @myarray = qw(
    rs30000489 
    rs903484 
    rs24567;rs324987;rs234985 
    rs5905002 
    rs32456;rs2349085 
); 

my @otherarray = qw(
    rs3249487 
    rs30000489 
    rs325987 
    rs324987 
    rs234967 
    rs32456 
    rs234567 
); 

my %my_hash = unique(@myarray); 
print Dumper \%my_hash if DEBUG; 

my %other_hash = unique(@otherarray); 
print Dumper \%other_hash if DEBUG; 

my %intersection =(); 
for my $item (keys %my_hash){ 
    if(exists $other_hash{$item}){ 
    $intersection{$item} ++; 
    } 
} 
print Dumper \%intersection if DEBUG; 
Смежные вопросы