2010-01-22 5 views
7

Je suis un programmeur Java/C++ et Ruby est mon premier langage de script. Je trouve parfois que je ne l'utilise pas de manière aussi productive que possible dans certains domaines, comme celui-ci par exemple:Conseil rapide: Comment cela devrait-il être écrit en Ruby?

Objectif: analyser uniquement certaines lignes d'un fichier. Le modèle que je vais suivre est qu'il y a une très grande ligne avec une taille supérieure à 15, le reste étant nettement plus petit. Je veux ignorer toutes les lignes avant (et y compris) le grand.

def do_something(str) 
    puts str 
end 


str = 
'ignore me 
me too! 
LARGE LINE ahahahahha its a line! 
target1 
target2 
target3' 

flag1 = nil 
str.each_line do |line| 
    do_something(line) if flag1 
    flag1 = 1 if line.size > 15 
end 

j'ai écrit cela, mais je pense qu'il pourrait être écrit beaucoup mieux, à savoir, il doit y avoir une meilleure façon de mettre un drapeau. Des recommandations pour écrire de belles lignes de Ruby sont également les bienvenues.

Note/Clarification: Je dois imprimer TOUTES les lignes APRÈS la première apparition de la LARGE LINE.

+0

Pouvez-vous définir «mieux» votre boucle fait exactement ce que vous voulez dans seulement quelques lignes de code et il est très facile de lire et de comprendre l'intention. – Beanish

+0

Mieux vaut pas par la performance, mais mieux. Les exemples fournis jusqu'ici sont ce que je recherche (surtout, si seulement les gens relisaient mieux la clarification). – Zombies

Répondre

10
str.lines.drop_while {|l| l.length < 15 }.drop(1).each {|l| do_something(l) } 

J'aime, parce que si vous le lisez de gauche à droite, il lit presque exactement comme votre description originale:

diviser la chaîne en lignes et laisser tomber des lignes plus courtes que 15 caractères Ensuite, supprimez une autre ligne (c'est-à-dire la première avec plus de 14 caractères). Ensuite, faites quelque chose avec chaque ligne restante.

Vous ne comprenez même pas besoin de nécessairement Ruby, ou la programmation du tout pour être en mesure de vérifier si cela est exact.

+0

Vous pouvez vous débarrasser de cette baisse supplémentaire si vous modifiez la condition à <=. Je n'ai jamais entendu parler de drop_while. Merci! – Farrel

+0

@Farrel: Non, vous ne pouvez pas. Si la longue ligne a plus de 15 caractères, elle agira exactement comme avant. S'il a exactement 15 caractères, il laissera tomber toute la chaîne. – sepp2k

+0

Farrel: Si la longue ligne comporte plus de 15 caractères (comme dans l'exemple), vous aurez toujours besoin de la goutte supplémentaire. En outre, je dois convenir que drop_while est assez soigné. – abeger

3
require 'enumerator' # Not needed in Ruby 1.9 

str.each_line.inject(false) do |flag, line| 
    do_something(line) if flag 
    flag || line.size > 15 
end 
1
lines = str.split($/) 
start_index = 1 + lines.find_index {|l| l.size > 15 } 
lines[start_index..-1].each do |l| 
    do_something(l) 
end 
+0

cela fonctionne-t-il en 1.8.6? Je reçois une erreur 'lignes' de la méthode non définie – Zombies

+0

Non, les lignes sont nouvelles en 1.8.7. Je vais mettre à jour la réponse pour utiliser split. – mckeed

+0

Dans 1.8.6, les chaînes sont déjà considérées comme un tableau de lignes, donc vous n'en avez pas besoin. En 1.9, cependant, les chaînes sont considérées comme un tableau de lignes, de caractères, d'octets ou de points de code, par conséquent vous devez dire explicitement quel comportement vous voulez. –

Questions connexes