1

ruby で 2 つのオブジェクトの配列をマージしようとしています。オブジェクトには 2 つの関連フィールドがあります。idreach_cost

結果の配列に一意の ID を含めたいと思います。衝突の場合、各オブジェクトは最小の reach_cost になります。

ランニング;

result = a1 | a2;

さまざまな結果が得られます。 a1の要素がa2の要素よりも優先されるようです。

もちろん、両方の配列を反復してelement.reach_costを手動で比較することもできますが、これは高パフォーマンス環境であり、このメソッドは非常に頻繁に呼び出されます。そのため、| のネイティブ コンポーネントを活用しようとしています。オペレーター。

|を指示することは可能ですか?オペレーターはあるオブジェクトを別のオブジェクトよりも優先しますか? おそらく <=> などをオーバーライドすることで?

| のソース コードを読みました。ドキュメントの演算子ですが、比較を行っているようには見えず、2番目の配列パラメーターよりも最初の配列パラメーターを優先するだけです。

4

2 に答える 2

3

解決策は簡単ですが、自分でパフォーマンスを確認する必要があります。

result = a1.concat(a2).sort_by!(&:reach_cost).uniq!(&:id)
于 2012-07-02T12:03:34.397 に答える
2

これらの配列をハッシュとして保存することをお勧めします。これにより、O(1) ID ルックアップが提供されます。コードは次のようになります。

h1 = {'1' => {:val => 2}, '2' => {:val => 3}}
h2 = {'1' => {:val => 5}, '2' => {:val => 1}}

def merge_hashes a, b
  a.reduce({}) do |memo, obj|
    k, v = obj

    # choose element with smallest :val
    memo[k] = if b[k][:val] < v[:val]
                b[k]
              else
                v
              end

    memo
  end
end

merge_hashes h1, h2 # => {"1"=>{:val=>2}, "2"=>{:val=>1}}

これはかなり速く動作するはずです。

ワンライナーが好きなら、これが1つです(コメントで@steenslagから親切に提供されました):

h1.merge(h2){|key,old,new| old[:val] < new[:val] ? old : new}
于 2012-07-02T12:15:19.400 に答える