Question

Je me retrouve avec des boucles comme PHP beaucoup en Ruby et il se sent mal quand le reste de la langue est si propre. Je termine avec le code comme ceci:

conditions_string = ''

zips.each_with_index do |zip, i|

    conditions_string << ' OR ' if i > 0
    conditions_string << "npa = ?"

end

# Now I can do something with conditions string

Je sens que je devrais être en mesure de faire quelque chose comme ceci

conditions_string = zips.each_with_index do |zip, i|

    << ' OR ' if i > 0
    << "npa = ?"

end

Est-il possible de définir une variable « Neat » avec un bloc Ruby?

Était-ce utile?

La solution

Vous ne semblez pas être accès zip dans votre boucle, de sorte que la suivante devrait fonctionner:

conditions_string = (['npa = ?'] * zips.length).join(' OR ')

Si vous avez besoin d'accéder à zip, vous pouvez utiliser:

conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')

Autres conseils

Puisque vous ne je vous suggère de ne pas utiliser réellement la valeur de zip,

zips.map {|zip| "npa = ?" }.join(" OR ")

mais en général je suggère à la recherche à la fonction Enumerable # inject pour éviter ce genre de boucles.

La première chose que je pensais était le suivant:

a = %w{array of strings}             => ["array", "of", "strings"]
a.inject { |m,s| m + ' OR ' + s }    => "array OR of OR strings"

Mais cela peut être fait avec seulement

a.join ' OR '

Et alors que je pense que vous aurez besoin que construire bientôt, pour dupliquer votre exemple précis que je pourrais simplement utiliser:

([' npa = ? '] * a.size).join 'OR'

Bien que d'autres ont donné des solutions plus idiomatiques à votre problème spécifique, il y a en fait une méthode fraîche Object#instance_eval, qui est un truc standard beaucoup Ruby DSLs utilisent. Il fixe self au récepteur de instance_eval dans son bloc:

court exemple:

x = ''
x.instance_eval do
    for word in %w(this is a list of words)
        self << word  # This means ``x << word''
    end
end
p x
# => "thisisalistofwords"

Il ne couvre pas tout pervasively de la manière la $_ de Perl, mais il vous permet d'envoyer implicitement les méthodes à un seul objet.

Dans 1.8.7+ vous pouvez utiliser each_with_object

Il remplace l'expression 'injectent' de DigitalRoss avec ceci:

a = %w{hello my friend}  => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " }  => "hello NOT my NOT friend NOT"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top