Dado que tengo una ENORME variedad, y un valor de ella. Quiero obtener el índice del valor en la matriz. ¿Hay alguna otra manera, en lugar de llamar a Array#index para conseguirlo? El problema surge de la necesidad de mantener realmente enorme variedad y llamadas Array#index enorme cantidad de veces.

Después de un par de intentos me encontré con que el almacenamiento en caché índices dentro de los elementos de almacenamiento de estructuras con (value, index) campos en lugar de en el valor en sí mismo da un paso enorme en el rendimiento (20x veces ganar).

Todavía me pregunto si hay una manera más cómoda de encontrar índice de es elemento sin almacenamiento en caché (o hay una buena técnica de almacenamiento en caché que aumentará el rendimiento).

InformationsquelleAutor gmile | 2011-06-05

7 Comentarios

  1. 117

    Convertir la matriz en una matriz. A continuación, busque la clave.

    array = ['a', 'b', 'c']
    hash = Hash[array.map.with_index.to_a]    # => {"a"=>0, "b"=>1, "c"=>2}
    hash['b'] # => 1
    • más rápido si la matriz es muy largo
    • Dependiendo de su caso de uso, esto podría ser problemático si hay valores duplicados. El método descrito anteriormente devolverá el equivalente o #rindex(última aparición de valor) Para obtener #índice de resultados equivalentes, lo que significa que el hash de devolver el primer índice del valor que tendríamos que hacer algo a lo largo de las líneas de inversión de la matriz antes de crear el hash luego restando la devuelve el valor del índice de la longitud total de la inicial de la matriz – 1. # (array.longitud – 1 ) – hash[‘b’]
    • No la conversión en un hash toma O(n) tiempo? Supongo que si va a ser utilizado más de una vez, entonces hash de conversión será más eficiente. pero para un solo uso, no es diferente de la iteración a través de la matriz?
    • Sí, y probablemente peor para un solo uso si realmente las materias como cálculo de hash no corto-circuito tan rápido como una comparación.
  2. 199

    ¿Por qué no utilizar el índice o rindex?

    array = %w( a b c d e)
    # get FIRST index of element searched
    puts array.index('a')
    # get LAST index of element searched
    puts array.rindex('a')

    índice: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-index

    rindex: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-rindex

    • Esto es exactamente lo que el OP dijo que NO quiere, debido al gran tamaño de su matriz. Matriz#índice es O(n) y haciendo que varias veces se matan en el rendimiento. Hash de búsqueda es O(1).
    • bueno, yo no recuerdo en el momento de mi respuesta de que ESTA era la mismo pregunta, tal vez el OP revisado la cuestión más tarde, lo que invalidaría esta respuesta.
    • ¿No dicen que había sido editado en un momento determinado, entonces?
    • Jeje, sí eso es cierto. Bien yo y el otro 30 personas estaban leyendo sobre él, a continuación,. Supongo :/
  3. 9

    Otras respuestas no tomar en cuenta la posibilidad de una entrada en una lista varias veces en una matriz. Esto devolverá un hash donde cada tecla es un objeto único en la matriz y cada valor es una serie de índices que corresponde a donde el objeto vidas:

    a = [1, 2, 3, 1, 2, 3, 4]
    => [1, 2, 3, 1, 2, 3, 4]
    
    indices = a.each_with_index.inject(Hash.new { Array.new }) do |hash, (obj, i)| 
        hash[obj] += [i]
        hash
    end
    => { 1 => [0, 3], 2 => [1, 4], 3 => [2, 5], 4 => [6] }

    Esto permite una búsqueda rápida de entradas duplicadas:

    indices.select { |k, v| v.size > 1 }
    => { 1 => [0, 3], 2 => [1, 4], 3 => [2, 5] }
  4. 6

    Hay una buena razón para no usar un hash? Las búsquedas son O(1) vs O(n) de la matriz.

    • El punto es … que yo estoy llamando #keys de hash, el cual devuelve una matriz que estoy utilizando. Aún así, yo podría pensar sobre mi arquitectura así…
  5. 2

    Tomar una combinación de @sawa, la respuesta y el comentario que aparece allí se podría implementar una «rápida» índice y rindex en la clase array.

    class Array
      def quick_index el
        hash = Hash[self.map.with_index.to_a]
        hash[el]
      end
    
      def quick_rindex el
        hash = Hash[self.reverse.map.with_index.to_a]
        array.length - 1 - hash[el]
      end
    end
  6. 2

    Si es un ordenados matriz puede utilizar un algoritmo de búsqueda Binaria (O(log n)). Por ejemplo, la ampliación de la Matriz de clase con esta funcionalidad:

    class Array
      def b_search(e, l = 0, u = length - 1)
        return if lower_index > upper_index
    
        midpoint_index = (lower_index + upper_index) / 2
        return midpoint_index if self[midpoint_index] == value
    
        if value < self[midpoint_index]
          b_search(value, lower_index, upper_index - 1)
        else
          b_search(value, lower_index + 1, upper_index)
        end
      end
    end
    • U creo que esto es fácil de leer? La lógica detrás de una respuesta es entregar el mensaje en una fácil manera y u puede hacer que su punto claramente uhn?
    • Realmente no es tan difícil de leer. Primera parte, la devolución si el límite inferior es mayor que el límite superior (la recursividad ha presentado). segunda parte verifica si necesitamos el lado izquierdo o el lado derecho comparando el punto medio m con el valor en ese punto al correo. si no tenemos la respuesta que queremos, nos recurse.
    • Creo que es mejor que el ego de la gente downvoting lugar de edición.
  7. 1

    Si su matriz tiene un orden natural utilizar el binario de búsqueda.

    Utilizar el binario de búsqueda.

    Binario de búsqueda ha O(log n) tiempo de acceso.

    Aquí son los pasos sobre cómo utilizar el binario de búsqueda,

    • Cuál es el orden de usted matriz? Por ejemplo, se ordenan por nombre?
    • Uso bsearch para encontrar elementos o índices

    Ejemplo de código

    # assume array is sorted by name!
    
    array.bsearch { |each| "Jamie" <=> each.name } # returns element
    (0..array.size).bsearch { |n| "Jamie" <=> array[n].name } # returns index

Dejar respuesta

Please enter your comment!
Please enter your name here