2016-12-18 3 views
4

Wie wird diese Funktion umgestaltet?Wie sollte ich diesen bedingten Code in Ruby umgestalten?

def split_description(first_n) 
    description_lines = description.split "\n" 
    line_num = description_lines.length 
    if line_num > first_n 
     @description_first = to_html(description_lines[0..first_n].join("\n")) 
     @description_remain = to_html(description_lines[first_n + 1..line_num].join("\n")) 
    elsif line_num > 1 
     @description_first = to_html(description_lines[0..first_n].join("\n")) 
     @description_remain = '' 
    else 
     @description_first = '' 
     @description_remain = '' 
    end 
    end 

Ich bin ein Starter-Ruby und stoßen diese rubocup Warnung: Method has too many lines. [13/10]

Hier finden Sie ganze Code url: https://github.com/RubyStarts3/YPBT-app/blob/master/views_objects/video_info_view.rb

Antwort

1

Da es in jedem Zustand blendeten verwendet oder ist, initialisieren die Instanzvariablen leer.

def split_description(first_n) 
    description_lines = description.split "\n" 
    line_num = description_lines.length 

    @description_first = '' 
    @description_remain = '' 

    if line_num > first_n 
     @description_first = to_html(description_lines[0..first_n].join("\n")) 
     @description_remain = to_html(description_lines[first_n + 1..line_num].join("\n")) 
    elsif line_num > 1 
     @description_first = to_html(description_lines[0..first_n].join("\n")) 
    end 
    end 

Ich würde auch die Logik für description_lines[first_n + 1..line_num].join("\n") ein Verfahren wie to_html(whatever_that_is(lines, from, to)) oder dergleichen bewegen. Dann ist es nicht so schlimm, wenn Sie den gleichen Anruf wiederholen und der Name beschreibt, was es macht.

1

Wenn first_n immer größer als 1 glaube ich Ihnen ein wenig die Antwort des Schwern ändern können:

... 

@description_first = to_html(description_lines[0..first_n].join("\n")) if line_num > 1 

    if line_num > first_n 
     @description_remain = to_html(description_lines[first_n + 1..line_num].join("\n")) 
    end 
end 
3

-Code

def split_description(description, first_n) 
    @description_first, @description_remain = 
    case description.count("\n") 
    when 0..first_n 
    [description, ''] 
    else 
    partition_description(description, first_n) 
    end.map(&:to_html) 
end 

def partition_description(description, first_n) 
    return ['', description] if first_n.zero? 
    offset = 0 
    description.each_line.with_index(1) do |s,i| 
    offset += s.size 
    return [description[0,offset], description[offset..-1]] if i == first_n 
    end 
end 

ich to_html('') #=> '' angenommen habe, aber wenn das nicht der ist Falls die Änderung einfach ist.

Beispiel

Damit wir die Wirkung von to_html sehen können, machen wir es auf diese Weise definieren.

def to_html(description) 
    description.upcase 
end 

description =<<_ 
It was the best of times 
it was the worst of times 
it was the age of wisdom 
it was the age of fools 
_ 

split_description(description, 0) 
@description_first 
    #=> "" 
@description_remain 
    #=> "IT WAS THE BEST OF TIMES\n..WORST OF TIMES\n..AGE OF WISDOM\n..AGE OF FOOLS\n" 

split_description(description, 1) 
@description_first 
    #=> "IT WAS THE BEST OF TIMES\n" 
@description_remain 
    #=> "IT WAS THE WORST OF TIMES\n..AGE OF WISDOM\n..AGE OF FOOLS\n" 

split_description(description, 2) 
@description_first 
    #=> "IT WAS THE BEST OF TIMES\nIT WAS THE WORST OF TIMES\n" 
@description_remain 
    #=> "IT WAS THE AGE OF WISDOM\nIT WAS THE AGE OF FOOLS\n" 

split_description(description, 3) 
@description_first 
    #=> "IT WAS THE BEST OF TIMES\n..WORST OF TIMES\n..AGE OF WISDOM\n" 
@description_remain 
    #=> "IT WAS THE AGE OF FOOLS\n" 

split_description(description, 4) 
@description_first 
    #=> "IT WAS THE BEST OF TIMES\n..WORST OF TIMES\n..AGE OF WISDOM\n..AGE OF FOOLS\n" 
@description_remain 
    #=> "" 

Erklärung

Zuerst erscheint, ist, dass description eine lokale Variable ist eine Zeichenfolge zu halten. Wenn ja, muss es ein Argument der Methode sein (zusammen mit first_n).

def split_description(description, first_n) 

Wir wollen Werte zu zwei Instanzvariablen zuweisen, so lassen beginnen die durch

Schreiben
@description_first, @description_remain = 

Es gibt wirklich zwei Schritte: die gewünschten Strings zu erhalten und Abbilden sie dann mit to_html. Konzentrieren wir uns also zunächst auf den ersten Schritt.

Wir werden nun Zustand auf die Anzahl der Zeilen in der Zeichenfolge

case description.count("\n") 

Lassen Sie uns zunächst mit dem Fall befassen, wo die Zeichenfolge keine Zeilenumbrüche enthält

when 0 
    [description, ''] 

Wenn die Zeichenfolge leer ist dies wird sei ['', '']; Andernfalls enthält es eine einzelne Zeichenfolge ohne Zeilenumbruch.

Angenommen, die Anzahl der Zeilenumbrüche in der Zeichenfolge liegt zwischen 1 und first_n. In diesem Fall soll @description_first der gesamte String sein und @description_remain soll leer sein.

when 1..first_n 
     [description, ''] 

Da beide when 0 und when 1..first_n geben den gleichen Array mit zwei Elementen, können wir sie kombinieren:

when 0..first_n 
    [description, ''] 

so weit zu kommen, first_n ist kleiner als die Anzahl von Zeilenumbrüchen. Ich habe eine andere Methode für den Fall verwendet, bei dem die Anzahl der Zeilenumbrüche größer als first_n ist.

else 
    partition_description(description, first_n) 

partition_description bestimmt einfach den Versatz in description des first_n ten Newline und dann partitioniert die Zeichenfolge entsprechend.

Schließlich müssen wir den Fall Anweisung beenden, Karte die Anordnung von zwei Strings zurück mit to_html und das Verfahren beenden

end.map(&:to_html) 
end 

Wie ich bereits erwähnt, habe ich to_html('') #=> '' angenommen. Das scheint mir der beste Ort zu sein, um mit leeren Saiten umzugehen.

Beachten Sie, dass ich mich direkt mit der Zeichenfolge beschäftigt habe, anstatt die Zeichenfolge in Zeilen aufzuteilen, die Zeilen zu bearbeiten und sie dann wieder einzufügen.

1

Dies sollte funktionieren:

def split_description(description, first_n = 0) 
    lines = description.each_line 
    @description_first = to_html(lines.take(first_n).join) 
    @description_remain = to_html(lines.drop(first_n).join) 
end 

take und drop alle Ihre Logik ersetzen, weil, wie @Cary Swoveland in einem Kommentar erwähnt:

  • wenn Sie zu viel nehmen, Sie am Ende mit das komplette Array, ohne Fehlermeldung
  • Wenn Sie zu viel abwerfen, beenden Sie ud mit einem leeren Array, ohne Fehlermeldung

Beispiel:

[1,2].take(99) #=> [1, 2] 
[1,2].drop(99) #=> [] 

Auch each_line gibt einen Array von Strings mit newlines noch vorhanden. No split, chomp oder join("\n") wird benötigt.

+1

Tatsächlich tut es! Netter, Eric. Bei Verwendung mit dem Beispiel in meiner Antwort erhalten wir die gleichen Ergebnisse. Sie machen sich die Tatsache zunutze, dass [1,2] .take (99) # => [1, 2] 'und' [1,2] .drop (99) # => [] 'machen können Es ist eine Herausforderung für den Leser zu verstehen, was vor sich geht. Ich schlage nicht vor, dass Sie das ändern, aber vielleicht fügen Sie einen oder zwei Kommentare hinzu, um zu klären. Was sage ich? Ein Kommentar in einer Methode, die an SO gesendet wurde? –

Verwandte Themen