2017-08-24 1 views
0
def bubble_sort_by(array) 
    sorted = false 

    until sorted 
    swapped = false 

    (array.length - 1).times do |i| 
     if yield(array[i],array[i+1]) > 0 
     array[i], array[i+1] = array[i+1], array[i] 
     swapped = true 
     end 
    end 

    if swapped == false 
     sorted = true 
    end 
    end 
    array 
end 


print bubble_sort_by(["hi","hello","hey"]) do |left,right| 
    left.length - right.length 
end 

Hallo ich bin eine Methode, die ein Array sortiert, aber einen Block akzeptieren. Der Block sollte zwei Argumente annehmen, die die zwei Elemente darstellen, die gerade verglichen werden, und das Element vom kleinsten zum größten sortieren (https://www.theodinproject.com/courses/ruby-programming/lessons/advanced-building-blocks).Drucken der Ausgabe von meiner Methode nicht möglich, lokaler Sprungfehler

Ich erwarte die Ausgabe ["hi", "hey", "hello"] drucken jedoch es in einer Fehlermeldung führt:

source_file.rb:8:in `block in bubble_sort_by': no block given (yield) (LocalJumpError) 
    from source_file.rb:7:in `times' 
    from source_file.rb:7:in `bubble_sort_by' 
    from source_file.rb:22:in `<main>' 

Kann mir jemand erklären, woher der Fehler kommen, und wie kann ich es beheben? Auch habe ich festgestellt, dass, wenn ich den Code array (von der vorletzten Zeile des Methodenblocks) zu ändern; der Code druckt ["hi", "hey", "hello"] aus, was ich wollte und daher sollte es bedeuten, dass mein Code korrekt ist. Daher meine Verwirrung darüber, woher der Fehler kam und wie kann ich das beheben?

Antwort

2

Kann mir jemand erklären, woher der Fehler kommen aus

Mangel an Klammern in Ihrem Code. Ihr Block bindet an print, nicht bubble_sort_by.

und wie kann ich es beheben?

Eine Möglichkeit ist, nicht auf der gleichen Linie zu drucken, aber eine temporäre Variable

sorted = bubble_sort_by(["hi","hello","hey"]) do |left,right| 
    left.length - right.length 
end 

print sorted 

Eine weitere Möglichkeit, verwenden, verwenden ein Block Syntax geschweiften Klammer, es stärker bindet.

print bubble_sort_by(["hi","hello","hey"]) { |left,right| left.length - right.length } 

Die am wenigsten bevorzugte Art und Weise (für mich) ist die Sortiermethode zu klammern, so dass es keinen Zweifel an dem Verfahren der Block gehört:

print(bubble_sort_by(["hi","hello","hey"]) do |left,right| 
    left.length - right.length 
end) 
+0

Dies irrelevant sein könnte, aber wie Sie sagen, Woran ist der Block gebunden? Gibt es auch irgendwelche Dokumente in Klammern? – roppo

+1

@roppo Bei mehreren verketteten Methodenaufrufen übergibt die 'do ... end'-Block-Syntax den Block an die Methode ganz links. Mit der '{...}' -Syntax wird sie an die am weitesten rechts liegende Methode übergeben. Siehe [die maßgebliche Dokumentation] (https://docs.ruby-lang.org/en/2.4.0/syntax/calling_methods_rdoc.html#label-Block+Argument) bezüglich der Syntax für Details. –

+1

@HolgerJust: Ich würde das aber nicht "Verkettung" nennen. Mehr wie ... "Nisten"? –

Verwandte Themen