1

我正在尝试在 ruby​​ 中合并两个对象数组。对象有两个相关字段;idreach_cost

我希望我的结果数组包含唯一的 id,其中每个对象在发生碰撞时具有最小的reach_cost。

跑步;

result = a1 | a2;

产生混合结果,似乎a1的元素优先于a2的元素。

我当然可以遍历两个数组并手动对element.reach_cost进行比较,但这是一个高性能环境,这种方法被称为非常多。出于这个原因,我试图利用 | 的原生组件。操作员。

是否可以指导 | 操作员更喜欢一个对象而不是另一个对象?也许通过覆盖 <=> 或类似的?

我已经阅读了 | 的源代码 文档中的运算符,但它似乎没有进行任何比较,只是更喜欢第一个数组参数而不是第二个。

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}}

这应该工作得很快。

如果你喜欢单线,这里有一个(@steenslag 在评论中友情提供):

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