Convertir un tableau en un index de hachage en Ruby

J'ai un tableau, et je veux faire un hash afin que je puisse rapidement se demander "est de X dans le tableau?".

En perl, il est facile (et rapide) pour ce faire:

my @array = qw( 1 2 3 );
my %hash;
@hash{@array} = undef;

Cela génère un hash qui ressemble à:

{
    1 => undef,
    2 => undef,
    3 => undef,
}

Le meilleur que j'ai trouvé en Ruby, c'est:

array = [1, 2, 3]
hash = Hash[array.map {|x| [x, nil]}]

qui donne:

{1=>nil, 2=>nil, 3=>nil}

Est-il un meilleur Ruby façon?

EDIT 1

Non, Tableau.inclure? n'est pas une bonne idée. Son lent. Il fait une requête en O(n) au lieu de O(1). Mon exemple du tableau a trois éléments à des fins de concision; assumer le réel a des millions d'éléments. Faisons une petite analyse comparative:

#!/usr/bin/ruby -w
require 'benchmark'

array = (1..1_000_000).to_a
hash = Hash[array.map {|x| [x, nil]}]

Benchmark.bm(15) do |x|
    x.report("Array.include?") { 1000.times { array.include?(500_000) } }
    x.report("Hash.include?") { 1000.times { hash.include?(500_000) } }
end

Produit:

                     user     system      total        real
Array.include?  46.190000   0.160000  46.350000 ( 46.593477)
Hash.include?    0.000000   0.000000   0.000000 (  0.000523)
  • N'oubliez pas de prendre en compte le temps qu'il faut pour faire la conversion. Bien sûr, si votre situation le permet, à l'aide d'un set pour commencer (comme suggéré par @Zach Langley) évite ce coût.
  • Pour être juste, l'indice de référence ci-dessus devrait inclure la conversion à partir d'un tableau de hachage
  • en théorie, c'est sûr. Dans la pratique, pas vraiment—c'est fondamentalement pas pertinent. La conversion est effectuée une fois, la recherche de beaucoup, beaucoup, beaucoup de fois. J'oublie ce que je travaillais lorsque j'ai demandé à ce, mais dans le programme de recherche a été probablement fait plusieurs millions de fois, après la conversion d'une fois.
InformationsquelleAutor derobert | 2009-01-04