leo*_*nel 48 ruby arrays ruby-on-rails
假设我有这个带有出货ID的数组.
s = Shipment.find(:all, :select => "id")
[#<Shipment id: 1>, #<Shipment id: 2>, #<Shipment id: 3>, #<Shipment id: 4>, #<Shipment id: 5>]
Run Code Online (Sandbox Code Playgroud)
带有货件ID的发票数组
i = Invoice.find(:all, :select => "id, shipment_id")
[#<Invoice id: 98, shipment_id: 2>, #<Invoice id: 99, shipment_id: 3>]
Run Code Online (Sandbox Code Playgroud)
shipment_id.要创建发票,我点击新发票,然后有一个包含发货的选择菜单,所以我可以选择"我为哪个发货创建发票".所以我只想显示尚未为其创建发票的货件清单.
所以我需要一组没有发票的货件.在上面的例子中,答案是1,4,5.
Kyl*_*cot 123
a = [2, 4, 6, 8]
b = [1, 2, 3, 4]
a - b | b - a # => [6, 8, 1, 3]
Run Code Online (Sandbox Code Playgroud)
pgu*_*rio 40
首先,您将获得发票中显示的shipping_id列表:
ids = i.map{|x| x.shipment_id}
Run Code Online (Sandbox Code Playgroud)
然后从原始数组中"拒绝"它们:
s.reject{|x| ids.include? x.id}
Run Code Online (Sandbox Code Playgroud)
注意:记住拒绝返回一个新数组,使用拒绝!如果要更改原始数组
den*_*lin 21
使用替代标志
irb(main):001:0> [1, 2, 3, 2, 6, 7] - [2, 1]
=> [3, 6, 7]
Run Code Online (Sandbox Code Playgroud)
Ruby 2.6引入了Array.difference:
[1, 1, 2, 2, 3, 3, 4, 5 ].difference([1, 2, 4]) #=> [ 3, 3, 5 ]
Run Code Online (Sandbox Code Playgroud)
所以在这里给出的情况下:
Shipment.pluck(:id).difference(Invoice.pluck(:shipment_id))
Run Code Online (Sandbox Code Playgroud)
似乎是解决问题的一种很好的解决方案。我一直是的热心追随者a - b | b - a,尽管有时想起来可能很棘手。
这当然可以解决这个问题。
纯红宝石溶液是
(a + b) - (a & b)
([1,2,3,4] + [1,3]) - ([1,2,3,4] & [1,3])
=> [2,4]
Run Code Online (Sandbox Code Playgroud)
哪里a + b会产生两个阵列之间的联合
与a & b回报交集
而union - intersection会返回差异
此前pgquardiario的答案仅包括单向差异.如果你想要两个数组的差异(因为它们都有一个唯一的项目),那么尝试类似下面的内容.
def diff(x,y)
o = x
x = x.reject{|a| if y.include?(a); a end }
y = y.reject{|a| if o.include?(a); a end }
x | y
end
Run Code Online (Sandbox Code Playgroud)
这应该在一个ActiveRecord查询中执行
Shipment.where(["id NOT IN (?)", Invoice.select(:shipment_id)]).select(:id)
Run Code Online (Sandbox Code Playgroud)
它输出SQL
SELECT "shipments"."id" FROM "shipments" WHERE (id NOT IN (SELECT "invoices"."shipment_id" FROM "invoices"))
Run Code Online (Sandbox Code Playgroud)
在Rails 4+中,您可以执行以下操作
Shipment.where.not(id: Invoice.select(:shipment_id).distinct).select(:id)
Run Code Online (Sandbox Code Playgroud)
它输出SQL
SELECT "shipments"."id" FROM "shipments" WHERE ("shipments"."id" NOT IN (SELECT DISTINCT "invoices"."shipment_id" FROM "invoices"))
Run Code Online (Sandbox Code Playgroud)
而不是select(:id)我推荐的ids方法.
Shipment.where.not(id: Invoice.select(:shipment_id).distinct).ids
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41760 次 |
| 最近记录: |