2016-05-03 108 views
0

我试图创建一个使用枚举的sort方法的功能的方法。如何覆盖枚举枚举排序方法

可以想象我有这个数据

data = [{project: 'proj', version: '1.1'}, {project: 'proj2', version: '1.11'}, {project: 'proj3', version: '1.2'}] 

我希望能够调用这样的方法:

data.natural_sort{|a,b| b[:version] <=> a[:version] } 

的实际调用发生这种情况会实现这样的事情:

data.sort{|a,b| MyModule.naturalize_str(b[:version]) <=> MyModule.naturalize_str(a[:version]) } 

继承人我目前的破码:

Enumerable.module_eval do 

    def natural_sort(&block) 
    if !block_given? 
     block = Proc.new{|a,b| Rearmed.naturalize_str(a[:version]) <=> Rearmed.naturalize_str(b[:version])} 
    end 

    sort do |a,b| 
     a = Rearmed.naturalize_str(a) 
     b = Rearmed.naturalize_str(b) 
     block.call(a,b) 
    end 
    end 

end 

它抛出一个错误,因为a和b是散列而不是我想要的版本。

回答

3

你正在与自己在这里工作。在你希望的​​区块中,你希望得到散列对象,但在实现中你明确地将ab转换为字符串。

在Ruby中,有两种排序方式,sort方法使用a,b对,而sort_by方法使用中间排序形式进行比较。 sort_by方法通常明显更快,因为它将变换应用到每个对象一次,而每次完成比较时,方法都会执行该方法。

这里有一个重写:

def natural_sort_by(&block) 
    if (block_given?) 
    sort_by do |o| 
     Rearmed.naturalize_str(yield(o)) 
    end 
    else 
    sort_by do |o| 
     Rearmed.naturalize_str(o) 
    end 
    end 
end 

然后,你可以这样调用它:

data.natural_sort_by { |o| o[:version] } 
+0

其实,现在有两个更多的方式来进行排序:'arr.min(arr.size)'和'arr.min_by(arr.size){...}'。 :-) –

+0

@CarySwoveland这是一个排序/获取交易,但它也遵循相同风格的a/b版本和一个单独的转换。 – tadman

+0

我已经有了natural_sort_by方法,但我也试图实现排序方法。 –