我试图使气泡更短,然后我想到了
class Array
def bubble_sort!(&block)
block = Proc.new { |a, b| a <=> b } unless block_given?
sorted = each_index.each_cons(2).none? do |i, next_i|
if block.call(self[i], self[next_i]) == 1
self[i], self[next_i] = self[next_i], self[i]
end
end until sorted
self
end
def bubble_sort(&prc)
self.dup.bubble_sort!(&prc)
end
end
我不太喜欢sorted = --sort code-- until sorted
上的东西。
我只想运行each_index.each_cons(s).none?
代码,直到返回true。我使用until
的情况很奇怪,但条件是我要运行的代码。无论如何,我的尝试似乎很尴尬,而红宝石通常有一种简洁的放置方法。有更好的方法吗?
答案 0 :(得分:2)
这只是我的意见
您是否曾经读过each
和map
的ruby源代码以了解它们的作用?
否,因为它们从方法名称中表达了明确的任务,并且如果您对其进行测试,则它们将获取一个对象,一些参数,然后向您返回一个值。
例如,如果我想测试String
方法split()
s = "a new string"
s.split("new")
=> ["a ", " string"]
您知道.split()
是否接受block
吗?
它是ruby的核心方法之一,但是要称它为90%的时间我都没有通过,我可以从名称.split()
和返回值中了解它的作用
关注您正在使用的对象,方法应完成的任务及其返回值。
我阅读了您的代码,但无法对其进行重构,我几乎无法理解代码的作用。
我决定写下一些观点,并可能会跟进:
1)暂时不要使用proc
,首先使面向对象的代码干净。
2)将bubble_sort!
分为几种方法,每种方法都有明确的任务
def ordered_inverted!
(bubble_sort!),def invert_values
,可能执行invert_values until sorted
,检查现有方法是否已执行此排序功能
3)编写这些方法的规范,tdd将促使您保持方法简单易测
4)如果这些方法不属于Array类,则将它们包括在适当的类中,有时过于复杂的方法仅在执行简单的String
操作。
5)阅读有关重构的书籍实际上可能会有所帮助,然后在不必要时尝试强制使用proc
和函数式编程。
答案 1 :(得分:1)
进一步研究之后,我确信最好的解决方案是
loop do
break if condition
end
无论是那个问题还是我在问题中提出的方式,但我认为loop do
版本更加清晰。
编辑:
哈,几周后,我解决了loop do
解决方案后,我偶然发现了一个更好的解决方案。您可以将while
或until
循环与一个空块一起使用,如下所示:
while condition; end
until condition; end
所以问题中的气泡排序示例可以这样写
class Array
def bubble_sort!(&block)
block = Proc.new { |a, b| a <=> b } unless block_given?
until (each_index.each_cons(2).none? do |i, next_i|
if block.call(self[i], self[next_i]) == 1
self[i], self[next_i] = self[next_i], self[i]
end
end); end
self
end
def bubble_sort(&prc)
self.dup.bubble_sort!(&prc)
end
end