2010-05-29 16 views
12

Estoy iterando sobre un conjunto muy grande de cadenas, que itera sobre un conjunto más pequeño de cadenas. Debido al tamaño, este método tarda un tiempo en hacerlo, por lo que para acelerarlo, estoy tratando de eliminar las cadenas del conjunto más pequeño que ya no es necesario usar a medida que avanza. A continuación se muestra el código actual:¿Eliminar durante la iteración en Ruby?

Ms::Fasta.foreach(@database) do |entry| 
     all.each do |set| 
      if entry.header[1..40].include? set[1] + "|" 
       startVal = entry.sequence.scan_i(set[0])[0] 

       if startVal != nil 
        @locations << [set[0], set[1], startVal, startVal + set[1].length] 
        all.delete(set) 
       end 
      end 
     end 
    end 

El problema que enfrentamos es que el camino más fácil, array.delete(string), agrega efectivamente una sentencia break para el bucle interior, lo que puede confundir los resultados. La única manera que sé cómo solucionar este problema es hacer esto:

Ms::Fasta.foreach(@database) do |entry| 
     i = 0 

     while i < all.length 
      set = all[i] 

      if entry.header[1..40].include? set[1] + "|" 
       startVal = entry.sequence.scan_i(set[0])[0] 

       if startVal != nil 
        @locations << [set[0], set[1], startVal, startVal + set[1].length] 
        all.delete_at(i) 
        i -= 1 
       end 
      end 

      i += 1 
     end 
    end 

Esto se siente tipo de descuidado a mí. ¿Hay una mejor manera de hacer esto?

+0

manera más fácil de hacer qué? ¿Qué estás intentando lograr? – wilhelmtell

+0

¿puede por favor no aceptar su propia respuesta a continuación? Claramente, no es el mejor – WattsInABox

Respuesta

36

uso delete_if

array.delete_if do |v| 
    if v.should_be_deleted? 
     true 
    else 
     v.update 
     false 
    end 
end 
+4

Gracioso si :). 'array.delete_if {| v | v.should_be_deleted? } ' – Yossi

+2

El sentido si perfecto si quería ejecutar' v.update' de manera elegante :) – trisweb

+0

FYI, eliminar es inmediato, por lo que si aumenta el bloque, los cambios todavía se reflejarán –

-1

uso 'arr.shift'

a=[1,2,3,4] 
while(a.length!=0) 
    print a 
    a.shift 
    print "\n" 
end 

de salida:

[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]

+0

este won 't trabajar '' ' a = [1,2,3,4] a.each hacer pone a.shift extremo => [3, 4] ' '' –

+0

@Ivan gracias por señalar esto. La última vez no probé con cada do por array, pero estaba seguro de que el cambio haría el trabajo requerido. Entonces lo edité ahora. ¡Revisalo! – apandey846

+0

también, 'Array # shift' es ineficiente, causará tiempo de ejecución de O (n²). –

Cuestiones relacionadas