[bcn-pm] Duda con arrays

JJ Merelo jjmerelo a gmail.com
dll feb 2 23:00:20 PST 2015


Madre mía, qué hack. Aplausos.

El 2 de febrero de 2015, 22:42, Salvador Fandiño <sfandino en gmail.com>
escribió:

>  On 02/02/2015 08:58 PM, Verónica Olmos González wrote:
>
>   ¡Hola a todos!
>
> Bueno, ante todo, como decía en mi presentación, soy bastante (muy) novata
> en Perl, así que es bastante probable que la esté liando con algo muy
> básico... pero me gustaría compartir mi problema con vosotros, por si
> alguno supiera darme alguna orientación (aunque sea simplemente remitirme a
> alguna página concreta de documentación).
>
>  El contexto de mi problema es el siguiente: parto de un array que
> contiene secuencias de nucleótidos (o sea, strings que deben estar formados
> por "A", "C", "G" o "T"). La cosa es que estos strings pueden contener,
> cualquiera de ellos, en determinada posición, el carácter "N", que no es
> "válido". Lo que hace el resto de mi programa es hacer comparaciones dos a
> dos entre cada elemento del array. Lo que quiero hacer, y el quid de mi
> duda: si en "x" posición de cualquier elemento encuentro una "N", debo
> borrar esa "x-ésima" posición en TODOS los elementos del array. Un ejemplo:
> si tengo @arr = ("AATN", "AATG", "TATG") debo quedarme con @arr2 = ("AAT",
> "AAT", "TAT").
>
>  Sin enrollarme con más explicaciones, os enseño el código con mi
> planteamiento:
>
>  @sequences = ("AATGTCAACGAN", "AATGTCAACGNA", "ATTGTCAACGTN",
>> "ATTGTGATCGTT");
>> for ($i = 0; $i <= scalar(@sequences); $i++) {
>>     if ($sequences[$i] =~ "N") {
>>
>        # Localizo las "N" y guardo su posición en un array
>
>          push(@pos,index($sequences[$i], "N"));
>     }
> }
>
>  # Elimino posiciones repetidas y ordeno los valores
>  my @pos = do { my %seen; grep { !$seen{$_}++ } @pos };
> @pos = sort @pos;
>
>  # Mi idea era, mediante expresiones regulares, poner "N" en todos los
> elementos de los arrays, en las posiciones guardadas, para luego eliminarlo
> todo evitando "corrimientos" en las posiciones
>
>  for ($i = 0; $i <= scalar(@sequences); $i++) {
>     for ($j = 0; $j <= scalar(@pos); $j++) {
>         substr($sequences[$i],$pos[$j],1) =~ s/\D/N/;
>     }
> }
>
>  Ahora bien, en el último bucle se me va todo de madre, permanece iterando
> continuamente.
>
>  La verdad es que seguro que estoy haciendo fatal algo tontísimo, pero no
> soy capaz de ver el origen del error, por lo que agradecería enormemente
> cualquier tipo de orientación.
>
>
>  Un saludo,
>  Verónica
>
>
> Para esto de la N hay un truco.
>
> Si te fijas, de todos los caracteres AGCTN solo la N tiene un 1 en el bit
> 3 (0x08) asi que puedes detectar donde hay Ns haciendo un OR de todas las
> sequencias y luego buscando los caracteres que tienen ese bit a uno en el
> resultado.
>
> A partir de ahi es fácil generar una mascara que al hacer AND con las
> secuencias originales ponga a cero las posiciones con N, y luego solo hay
> que borrar los ceros:
>
>   @sequences = ("AATGTCAACGAN",
>                 "AATGTCAACGNA",
>                 "ATTGTCAACGTN",
>                 "ATTGTGATCGTT");
>
>   my $mask = '';
>   $mask |= $_ for @sequences;
>   $mask =~ s/(.)/(ord($1) & 8) ? "\0" : "\xFF"/ge;
>
>   for (@sequences) {
>       $_ &= $mask;
>       tr/\0//;
>   }
>
>   use Data::Dumper;
>   print Dumper \@sequences;
>
>
>
> _______________________________________________
> llista dels Barcelona-pm
> Barcelona-pm en pm.org
> http://mail.pm.org/mailman/listinfo/barcelona-pm
> BCN Perl Mongers: http://barcelona.pm.org
>



-- 
JJ
------------ pr�a parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.pm.org/pipermail/barcelona-pm/attachments/20150203/59ccb237/attachment-0001.html>


Més informació sobre la llista de correu Barcelona-pm