[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