Rails 3. How to get the difference between two arrays?

Let’s say I have this array with shipments ids.

s = Shipment.find(:all, :select => "id")

[#<Shipment id: 1>, #<Shipment id: 2>, #<Shipment id: 3>, #<Shipment id: 4>, #<Shipment id: 5>]

Array of invoices with shipment id's

i = Invoice.find(:all, :select => "id, shipment_id")

[#<Invoice id: 98, shipment_id: 2>, #<Invoice id: 99, shipment_id: 3>]
  • Invoices belongs to Shipment.
  • Shipment has one Invoice.
  • So the invoices table has a column of shipment_id.

To create an invoice, I click on New Invoice, then there is a select menu with Shipments, so I can choose "which shipment am i creating the invoice for". So I only want to display a list of shipments that an invoice hasn't been created for.

So I need an array of Shipments that don't have an Invoice yet. In the example above, the answer would be 1, 4, 5.


a = [2, 4, 6, 8]
b = [1, 2, 3, 4]

a - b | b - a # => [6, 8, 1, 3]

First you would get a list of shipping_id's that appear in invoices:

ids = i.map{|x| x.shipment_id}

Then 'reject' them from your original array:

s.reject{|x| ids.include? x.id}

Note: remember that reject returns a new array, use reject! if you want to change the original array


Use substitute sign

irb(main):001:0> [1, 2, 3, 2, 6, 7] - [2, 1]
=> [3, 6, 7]