2016-05-03 16 views
0

Enumerablesのsortメソッドの機能を使用するメソッドを作成しようとしています。オーバーライド方法Enumerablesソート方法

私はこのようなメソッドを呼び出すことができるようにしたい私は、このデータを持っている

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では、a,bのペアでsortメソッドをソートする方法と、中間のソートフォームを使用して比較を行う方法の2つの方法があります。 sort_byのアプローチは、通常、各オブジェクトに変換を一度適用するので、大幅に高速ですが、比較が行われるたびにsortメソッドがそれを行います。

ここに書き換えます:

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

は実際には、並べ替えるには、2つのより多くの方法が存在することになります: 'arr.min(arr.size)'と 'arr.min_by(arr.size){...}'となります。 :-) –

+0

@CarySwovelandこれはソート/フェッチの取引ですが、a/bバージョンと同じスタイルにも、個々の変換も行います。 – tadman

+0

私はすでにnatural_sort_byメソッドを持っていますが、ソートメソッドも実装しようとしています。 –

関連する問題