Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 775
leonel Avatar asked Dec 26 '11 23:12

leonel


People also ask

How do you Diff two arrays?

To get the difference between two arrays: Use the filter() method to iterate over the first array. Check if each element is not contained in the second array. Repeat the steps, but this time iterate over the second array.

How do you find the common element in two arrays in Ruby?

We already know Array#intersection or Array#& methods which are used to find the common elements between arrays. The intersection or & methods return an empty array or array having the common elements in it as result.

How can you test if an item is included in an array Ruby?

This is another way to do this: use the Array#index method. It returns the index of the first occurrence of the element in the array. This returns the index of the first word in the array that contains the letter 'o'. index still iterates over the array, it just returns the value of the element.


2 Answers

a = [2, 4, 6, 8] b = [1, 2, 3, 4]  a - b | b - a # => [6, 8, 1, 3] 
like image 84
Kyle Decot Avatar answered Sep 24 '22 01:09

Kyle Decot


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

like image 40
pguardiario Avatar answered Sep 26 '22 01:09

pguardiario