2010-01-22 12 views
7

Sono un programmatore Java/C++ e Ruby è il mio primo linguaggio di scripting. A volte trovo che non lo sto usando in modo produttivo come in alcune aree, come ad esempio:Consigli rapidi: come dovrebbe essere scritto in Ruby?

Obiettivo: analizzare solo alcune righe da un file. Lo schema che sto seguendo è che c'è una linea molto grande con una dimensione maggiore di 15, il resto è decisamente più piccolo. Voglio ignorare tutte le righe prima (e compreso) quella grande.

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 

ho scritto questo, ma penso che potrebbe essere scritto molto meglio, vale a dire, ci deve essere un modo migliore di impostazione di un flag. Anche le raccomandazioni su come scrivere bellissime linee di Ruby sono le benvenute.

Nota/Chiarimento: Ho bisogno di stampare TUTTE le linee DOPO la prima apparizione della LINEA GRANDE.

+0

Puoi definire "migliore" il tuo do do fa esattamente quello che vuoi in poche righe di codice ed è molto facile da leggere e capire l'intenzione. – Beanish

+0

Meglio non dalle prestazioni, ma dall'aspetto migliore. Gli esempi forniti finora sono ciò che sto cercando (soprattutto se solo le persone rileggerebbero meglio il chiarimento). – Zombies

risposta

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

Mi piace questo, perché se lo si legge da sinistra a destra, si legge quasi esattamente come la tua descrizione originale:

dividere la stringa in linee e rilasciare le linee più corta 15 caratteri. Quindi rilascia un'altra linea (ad esempio la prima con più di 14 caratteri). Quindi fai qualcosa con ogni linea rimanente.

Non è nemmeno necessario comprendere necessariamente Ruby o programmare su tutti per verificare se questo è corretto.

+0

È possibile eliminare tale ulteriore perdita se si modifica la condizione su <=. Mai saputo di drop_while. Grazie! – Farrel

+0

@ Farrel: No, non puoi. Se la lunga fila ha più di 15 caratteri, funzionerà esattamente come prima. Se ha esattamente 15 caratteri, lascerà cadere l'intera stringa. – sepp2k

+0

Farrel: se la lunga linea è lunga più di 15 caratteri (come nell'esempio), sarà comunque necessario il drop aggiuntivo. Inoltre, devo convenire che drop_while è abbastanza pulito. – 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

funziona in 1.8.6? Ricevo l'errore 'linee' del metodo non definito – Zombies

+0

No, le linee sono nuove in 1.8.7. Aggiornerò la risposta per usare split. – mckeed

+0

In 1.8.6, le stringhe sono già considerate una matrice di linee, pertanto non è necessario. In 1.9, tuttavia, le stringhe sono considerate un array di righe, caratteri, byte o punti di codice, quindi devi dire esplicitamente quale comportamento vuoi. –

Problemi correlati