Ruby on rails 基于外键合并两个数组

Ruby on rails 基于外键合并两个数组,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个搜索功能,它查找两个模型a和B。结果是@a和@B。两者均由制造商id和型号id组成: 在我看来,我的结果应该仍然能够参考制造商和模型,并获得具体的参数 <% @output.each do |r| %> <tr> <td><%= r.manufacturer.name %></td> <td><%= link_to r.model.name, edit_model_path(r) %>

我有一个搜索功能,它查找两个模型a和B。结果是@a和@B。两者均由制造商id和型号id组成:

在我看来,我的结果应该仍然能够参考制造商和模型,并获得具体的参数

<% @output.each do |r| %>
  <tr>
    <td><%= r.manufacturer.name %></td>
    <td><%= link_to r.model.name, edit_model_path(r) %></td>
    <td colspan=2>
        <%= link_to "View", a_path(r), class: "button btn btn-success btn-xs" %> 
        <%= link_to "Edit", edit_b_path(r), class: "button btn btn-warning btn-xs" %>
    </td>
    <td colspan=2>
        <%= link_to "View", b_path(r), class: "button btn btn-success btn-xs" %> 
        <%= link_to "Edit", edit_b_path(r), class: "button btn btn-warning btn-xs" %>
    </td>
  </tr>
<% end %>
请指导我。

您可以使用和查找具有通用ID的对象

更新:现在使用set union来输出每个id组合

@a = [
  { id: 6, manufacturer_id: 1, model_id: 6 },
  { id: 10, manufacturer_id: 1, model_id: 10 },
  { id: 111, manufacturer_id: 3, model_id: 4 }
]

@b = [
  { id: 167, manufacturer_id: 1, model_id: 6 },
  { id: 175, manufacturer_id: 1, model_id: 10 },
  { id: 176, manufacturer_id: 2, model_id: 3 }
]

def group_by_ids(array)
  array.group_by { |h| h.values_at(:manufacturer_id, :model_id) }
end

a_by_ids = group_by_ids(@a)
b_by_ids = group_by_ids(@b)

common_keys = a_by_ids.keys & b_by_ids.keys
all_keys    = a_by_ids.keys | b_by_ids.keys

result = all_keys.map do |ids|
  a_objects = a_by_ids[ids]
  b_objects = b_by_ids[ids]
  a_object  = a_objects && a_objects.first
  b_object  = b_objects && b_objects.first
  [*ids, a_object, b_object]
end
它输出:

[[1,
  6,
  {:id=>6, :manufacturer_id=>1, :model_id=>6},
  {:id=>167, :manufacturer_id=>1, :model_id=>6}],
 [1,
  10,
  {:id=>10, :manufacturer_id=>1, :model_id=>10},
  {:id=>175, :manufacturer_id=>1, :model_id=>10}],
 [3, 4, {:id=>111, :manufacturer_id=>3, :model_id=>4}, nil],
 [2, 3, nil, {:id=>176, :manufacturer_id=>2, :model_id=>3}]]
因此,您得到一个数组数组,其中每个子数组如下所示:

[manufacturer_id, model_id, a_object, b_object]
您可能需要稍微调整视图,但每个数组中都应该有足够的信息。

您可以使用和查找具有公共ID的对象

更新:现在使用set union来输出每个id组合

@a = [
  { id: 6, manufacturer_id: 1, model_id: 6 },
  { id: 10, manufacturer_id: 1, model_id: 10 },
  { id: 111, manufacturer_id: 3, model_id: 4 }
]

@b = [
  { id: 167, manufacturer_id: 1, model_id: 6 },
  { id: 175, manufacturer_id: 1, model_id: 10 },
  { id: 176, manufacturer_id: 2, model_id: 3 }
]

def group_by_ids(array)
  array.group_by { |h| h.values_at(:manufacturer_id, :model_id) }
end

a_by_ids = group_by_ids(@a)
b_by_ids = group_by_ids(@b)

common_keys = a_by_ids.keys & b_by_ids.keys
all_keys    = a_by_ids.keys | b_by_ids.keys

result = all_keys.map do |ids|
  a_objects = a_by_ids[ids]
  b_objects = b_by_ids[ids]
  a_object  = a_objects && a_objects.first
  b_object  = b_objects && b_objects.first
  [*ids, a_object, b_object]
end
它输出:

[[1,
  6,
  {:id=>6, :manufacturer_id=>1, :model_id=>6},
  {:id=>167, :manufacturer_id=>1, :model_id=>6}],
 [1,
  10,
  {:id=>10, :manufacturer_id=>1, :model_id=>10},
  {:id=>175, :manufacturer_id=>1, :model_id=>10}],
 [3, 4, {:id=>111, :manufacturer_id=>3, :model_id=>4}, nil],
 [2, 3, nil, {:id=>176, :manufacturer_id=>2, :model_id=>3}]]
因此,您得到一个数组数组,其中每个子数组如下所示:

[manufacturer_id, model_id, a_object, b_object]

您可能需要稍微调整视图,但每个数组中都应该有足够的信息。

这里是另一种方法

[@a, @b].flatten.group_by do |row|
  row.values_at(:manufacturer_id, :model_id)
end.reduce([]) do |output, ((manufacturer_id, model_id), data)|
  output << data.reduce({}) { |memo, x| memo.merge(x) }
end

如果需要进行任何类型的重命名以防止哈希值发生冲突,可以修改传递给data.reduce的块以进行更细致的合并。

这里是另一种方法

[@a, @b].flatten.group_by do |row|
  row.values_at(:manufacturer_id, :model_id)
end.reduce([]) do |output, ((manufacturer_id, model_id), data)|
  output << data.reduce({}) { |memo, x| memo.merge(x) }
end

如果需要进行任何类型的重命名以避免哈希值发生冲突,则可以修改传递给data.reduce的块以进行更细微的合并。

是否有a和b的正确示例,以及输出应该是什么?Ruby数组介于[]之间。另外,请不要使用变量或属性名,而是使用Ruby objects 1、model_x、@EricDuminil的具体示例。我根据您的建议添加了实际示例。我之所以想这样说,是为了让人们能很容易地看到它。谢谢a是a对象的数组,b是b对象的数组,您想按制造商id和型号id对a和b进行分组?a和b是型号吗?a和b是来自同一模型的对象数组吗?当您提供一个示例通常是一件好事时,请执行以下操作:1。确保输入是有效的Ruby对象,例如,no。。。;2.尽可能简短地给出示例,同时在这里指出要点,三个键值对;3帮助希望使用您的示例运行代码的读者避免不相关的复杂情况,避免日期或时间值;4显示给定示例的预期结果;和5为每个输入对象分配一个变量,例如,a=[你有a和b的正确例子吗,你的输出应该是什么?Ruby数组介于[]。另外,请不要使用变量或属性名称,但Ruby objects 1、model_x、@EricDuminil的具体示例我根据您的建议添加了实际示例。我之所以要这样说,以便人们可以轻松地看到它。谢谢!a是a对象的数组,b是b对象的数组,您希望按ma将a和b分组nufacturer_id和model_id?是A和B模型?是来自同一模型的对象的A和B数组吗?当您提供一个示例时,通常是一件好事,请执行以下操作:1.确保输入是有效的Ruby对象,例如,否…;2.尽可能简短的示例,同时仍然在这里强调重点,三个键值对;3.帮助读者希望通过避免不相关的复杂性来运行示例代码此处避免日期或时间值;4显示给定示例的预期结果;5为每个输入对象分配一个变量,例如a=[您提供的两种方法都给了我一个错误,'undefined method'values_at'for nil:NilClass`。我查看了API,不知道为什么会发生这种情况。使用double reduce:。如果我正确理解您的代码,您希望@a和@b数组的元素响应合并,这可能不是这里的情况。您提供的两种方法ided给了我一个错误,'undefined method'values_at'for nil:NilClass`。我查看了API,不知道为什么会发生这种情况。double reduce的使用很好:。如果我正确理解您的代码,您希望@a和@b数组的元素响应合并,这里可能不是这种情况。我收到了一个错误,@a和@b数组的未定义方法'group_by'for nil:NilCla这意味着没有定义@a或@b。对于那些不匹配的结果,如果其中任何一个不存在,数组中的一个对象或b对象是否可能为0?例如[manufacturer_id,model_id,a_对象,0],因为b_对象不存在。确定。您使用的是哪个ruby版本?给您。a或b对象现在允许为零。我收到一个错误,未定义此数组中nil:NilClass的方法“group_by”。group_by{h[:manufacturer_id],h[:model_id]}行。这意味着未定义@a或@b。对于那些不匹配的结果,如果其中任何一个不存在,数组中的\u对象或b\u对象是否可能为0?例如,[制造商\u id,模型\u id,a\u对象,0],因为b\u对象不存在。确定。您使用的是哪个ruby版本?给您。现在允许a或b对象为零。